Problem:
Score : 500 points

Problem Statement

Let N be a positive integer.

There is a numerical sequence of length 3N, a = (a_1, a_2, ..., a_{3N}).
Snuke is constructing a new sequence of length 2N, a', by removing exactly N elements from a without changing the order of the remaining elements.
Here, the score of a' is defined as follows: (the sum of the elements in the first half of a') - (the sum of the elements in the second half of a').

Find the maximum possible score of a'.

Constraints

1 ≤ N ≤ 10^5

a_i is an integer.

1 ≤ a_i ≤ 10^9

Partial Score

In the test set worth 300 points, N ≤ 1000.

Input

Input is given from Standard Input in the following format:

N
a_1 a_2 ... a_{3N}

Output

Print the maximum possible score of a'.

Sample Input 1

2
3 1 4 1 5 9

Sample Output 1

1

When a_2 and a_6 are removed, a' will be (3, 4, 1, 5), which has a score of (3 + 4) - (1 + 5) = 1.

Sample Input 2

1
1 2 3

Sample Output 2

-1

For example, when a_1 are removed, a' will be (2, 3), which has a score of 2 - 3 = -1.

Sample Input 3

3
8 2 2 7 4 6 5 3 8

Sample Output 3

5

For example, when a_2, a_3 and a_9 are removed, a' will be (8, 7, 4, 6, 5, 3), which has a score of (8 + 7 + 4) - (6 + 5 + 3) = 5.

Solution in LuaJIT (2.0.4) (judge verdict: Accepted)

local mma = math.max
local mfl, mce, mmi = math.floor, math.ceil, math.min

local AvlTree = {}
AvlTree.makenode = function(self, val, parent)
  local i = self.box[#self.box]
  table.remove(self.box)
  self.v[i], self.p[i] = val, parent
  self.lc[i], self.rc[i], self.l[i], self.r[i] = 0, 0, 1, 1
  return i
end
AvlTree.create = function(self, lessthan, n)
  self.lessthan = lessthan
  self.root = 1
  self.box = {}
  for i = n + 1, 2, -1 do table.insert(self.box, i) end
  -- value, leftCount, rightCount, left, right, parent
  self.v, self.lc, self.rc, self.l, self.r, self.p = {}, {}, {}, {}, {}, {}
  for i = 1, n + 1 do
    self.v[i], self.p[i] = 0, 1
    self.lc[i], self.rc[i], self.l[i], self.r[i] = 0, 0, 1, 1
  end
end

AvlTree.recalcCount = function(self, i)
  if 1 < i then
    if 1 < self.l[i] then self.lc[i] = 1 + mma(self.lc[self.l[i]], self.rc[self.l[i]])
    else self.lc[i] = 0
    end
    if 1 < self.r[i] then self.rc[i] = 1 + mma(self.lc[self.r[i]], self.rc[self.r[i]])
    else self.rc[i] = 0
    end
  end
end
AvlTree.recalcCountAll = function(self, i)
  while 1 < i do
    self:recalcCount(i)
    i = self.p[i]
  end
end

AvlTree.rotR = function(self, child, parent)
  local granp = self.p[parent]
  self.r[child], self.l[parent] = parent, self.r[child]
  self.p[child], self.p[parent] = granp, child
  self.p[self.l[parent]] = parent
  if 1 < granp then
    if self.l[granp] == parent then
      self.l[granp] = child
    else
      self.r[granp] = child
    end
  else
    self.root = child
  end
  self:recalcCountAll(parent)
end

AvlTree.rotL = function(self, child, parent)
  local granp = self.p[parent]
  self.l[child], self.r[parent] = parent, self.l[child]
  self.p[child], self.p[parent] = granp, child
  self.p[self.r[parent]] = parent
  if 1 < granp then
    if self.r[granp] == parent then
      self.r[granp] = child
    else
      self.l[granp] = child
    end
  else
    self.root = child
  end
  self:recalcCountAll(parent)
end

AvlTree.add = function(self, val)
  if self.root <= 1 then self.root = self:makenode(val, 1) return end
  local pos = self.root
  local added = false
  while not added do
    if self.lessthan(val, self.v[pos]) then
      if 1 < self.l[pos] then
        pos = self.l[pos]
      else
        self.l[pos] = self:makenode(val, pos)
        pos = self.l[pos]
        added = true
      end
    else
      if 1 < self.r[pos] then
        pos = self.r[pos]
      else
        self.r[pos] = self:makenode(val, pos)
        pos = self.r[pos]
        added = true
      end
    end
  end
  while 1 < pos do
    local child, parent = pos, self.p[pos]
    if parent <= 1 then
      break
    end
    self:recalcCount(parent)
    if self.l[parent] == child then
      if self.lc[parent] - 1 == self.rc[parent] then
        pos = parent
      elseif self.lc[parent] - 2 == self.rc[parent] then
        self:recalcCount(child)
        if self.lc[child] - 1 == self.rc[child] then
          self:rotR(child, parent)
        else
          local cr = self.r[child]
          self:rotL(cr, child)
          self:rotR(cr, parent)
        end
        pos = 1
      else
        self:recalcCountAll(child)
        pos = 1
      end
    else -- parent.r == child
      if self.rc[parent] - 1 == self.lc[parent] then
        pos = parent
      elseif self.rc[parent] - 2 == self.lc[parent] then
        self:recalcCount(child)
        if self.rc[child] - 1 == self.lc[child] then
          self:rotL(child, parent)
        else
          local cl = self.l[child]
          self:rotR(cl, child)
          self:rotL(cl, parent)
        end
        pos = 1
      else
        self:recalcCountAll(child)
        pos = 1
      end
    end
  end
end

AvlTree.rmsub = function(self, node)
  while 1 < node do
    self:recalcCount(node)
    if self.lc[node] == self.rc[node] then
      node = self.p[node]
    elseif self.lc[node] + 1 == self.rc[node] then
      self:recalcCountAll(self.p[node])
      node = 1
    else
      if self.lc[self.r[node]] == self.rc[self.r[node]] then
        self:rotL(self.r[node], node)
        node = 1
      elseif self.lc[self.r[node]] + 1 == self.rc[self.r[node]] then
        local nr = self.r[node]
        self:rotL(nr, node)
        node = nr
      else
        local nrl = self.l[self.r[node]]
        self:rotR(nrl, self.r[node])
        self:rotL(nrl, node)
        node = nrl
      end
    end
  end
end

AvlTree.pop = function(self)
  local node = self.root
  while 1 < self.l[node] do
    node = self.l[node]
  end
  local v = self.v[node]
  if 1 < self.p[node] then
    self.p[self.r[node]] = self.p[node]
    self.l[self.p[node]] = self.r[node]
    self:rmsub(self.p[node])
  else
    self.p[self.r[node]] = 1
    self.root = self.r[node]
  end
  table.insert(self.box, node)
  return v
end

AvlTree.new = function(lessthan, n)
    local obj = {}
    setmetatable(obj, {__index = AvlTree})
    obj:create(lessthan, n)
    return obj
end

local n = io.read("*n", "*l")
local a = {}
local s = io.read()
for str in s:gmatch("%d+") do
  table.insert(a, tonumber(str))
end
local leftsum = {0}
local avleft = AvlTree.new(function(x, y) return x < y end, n + 1)
for i = 1, n do
  leftsum[1] = leftsum[1] + a[i]
  avleft:add(a[i])
end
for i = 1, n do
  avleft:add(a[i + n])
  leftsum[i + 1] = leftsum[i] + a[i + n] - avleft:pop()
end
local avright = AvlTree.new(function(x, y) return x > y end, n + 1)
local rightsum = {0}
for i = 1, n do
  rightsum[1] = rightsum[1] + a[i + 2 * n]
  avright:add(a[i + 2 * n])
end
for i = 1, n do
  avright:add(a[2 * n + 1 - i])
  rightsum[i + 1] = rightsum[i] + a[2 * n + 1 - i] - avright:pop()
end
local ret = leftsum[1] - rightsum[n + 1]
for i = 2, n + 1 do
  ret = mma(ret, leftsum[i] - rightsum[n + 2 - i])
end
print(ret)