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 Scala (2.11.7) (judge verdict: Wrong Answer)

import java.io.{BufferedReader, InputStream, InputStreamReader}
import java.util.StringTokenizer

import scala.collection.mutable
import scala.util.Sorting
import math.{abs, max, min}
import scala.reflect.ClassTag

object Main {
  val MOD = 1000000007
  def solve(): Unit = {
    val sc = new InputReader(System.in)
    val N = sc.nextInt()

    val left = Array.fill[Long](N)(sc.nextLong())
    val leftT = new Heap[Long](N + 1)
    left.indices foreach (i => leftT.push(left(i)))
    val mid_right = Array.fill[Long](2 * N)(sc.nextLong())
    val mid = mid_right.take(N)

    Sorting.quickSort(mid_right)
    val rightT = new Heap[Long](N)
    val unusedRightT = new Heap[Long](N)
    (0 until N) foreach (i => rightT.push(mid_right(i)))
    (N until 2 * N) foreach (i => unusedRightT.push(mid_right(i)))

    var L: Long = ((0 until N) map (left(_))).sum
    var R: Long = ((0 until N) map (mid_right(_))).sum
    var ans: Long = L - R

    (0 until N) foreach { i =>
      val x = mid(i)

      // (y) (x) -> (x) ()
      leftT.push(x)
      L += x - leftT.pop()

      // (y) (x) -> () (y)
      if (rightT.remove(x)) {
        val y = unusedRightT.pop()
        rightT.push(y)
        R -= x - y
      } else {
        unusedRightT.remove(x)
      }

      ans = max(ans, L - R)
    }

    println(ans)
  }


  def main(args: Array[String]): Unit = {
    solve()
  }


  class InputReader(val stream: InputStream) {
    private val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private var tokenizer: StringTokenizer = null

    def next: String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = next.toInt
    def nextLong(): Long = next.toLong
    def nextChar(): Char = next.charAt(0)
  }

  class Heap[@specialized(Int, Long) A: ClassTag](size: Int)(implicit o: Ordering[A]) {
    private var n: Int = 0
    private val nodes = {
      val k = {
        var n = size
        var i = 0
        while(n > 0) {
          n >>= 1
          i += 1
        }
        i
      }
      Array.ofDim[A]((1 << k) - 1)
    }

    def push(x: A): Unit = {
      n += 1

      def step(i: Int): Int = {
        val p = (i - 1) / 2
        i match {
          case 0 => 0
          case _ if o.lteq(nodes(p), x) => i
          case _ =>
            nodes(i) = nodes(p) // 親を下ろす
            step(p)
        }
      }

      nodes(step(n - 1)) = x
    }

    def remove(x: A): Boolean = {
      val pos = findPos(x)
      if (pos == -1) false
      else {
        removeByPos(findPos(x))
        true
      }
    }

    def pop(): A = {
      val x = nodes(0)
      removeByPos(0)
      x
    }

    private def findPos(x: A): Int = {
      def step(i: Int): Int = {
        if (i >= n) -1
        else if (nodes(i) == x) i
        else {
          val pos = step(2 * i + 1)
          if (pos != -1) pos
          else step(2 * i + 2)
        }
      }
      step(0)
    }

    private def removeByPos(i: Int): Unit = {
      val x = nodes(n - 1)
      n -= 1

      def step(i: Int): Int = {
        val l = 2 * i + 1
        val r = 2 * i + 2
        if (l >= n) i
        else {
          val c = if (r >= n && o.lteq(nodes(r), nodes(l))) r else l
          if (o.lteq(x, nodes(c))) i
          else {
            nodes(i) = nodes(c)
            step(c)
          }
        }
      }

      nodes(step(i)) = x
    }

    def peek: A = nodes(0)
  }
}