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 Rust (1.15.1) (judge verdict: Wrong Answer)

#![allow(unused_imports)]
use std::io::{ self, Write };
use std::str::FromStr;
use std::cmp::{ min, max };
use std::collections::{ BinaryHeap, VecDeque };

macro_rules! trace {
    ($var:expr) => ({
        let _ = writeln!(&mut std::io::stderr(), ">>> {} = {:?}", stringify!($var), $var);
    })
}
macro_rules! swap { ($a:expr, $b:expr) => ({ let t = $b; $b = $a; $a = t; }) }

fn main() {
    let mut sc = Scanner::new();

    let n = sc.cin();

    let mut xs = vec![0; 3 * n];
    let mut a = vec![0; n + 1];
    let mut b = vec![0; n + 1];

    for i in 0..(3 * n) {
        let x: i64 = sc.cin();
        xs[i] = x;
    }

    {
        let mut sum = 0;
        let mut top = BinaryHeap::new();
        for i in 0..n {
            let x = xs[i];
            top.push(-x);
            sum += x;
        }
        a[0] = sum;
        for i in 0..n {
            let x = xs[i + n];
            let y = -top.pop().unwrap();
            if x > y {
                sum = sum - y + x;
                top.push(-x);
            } else {
                top.push(-y);
            }
            a[i + 1] = sum;
        }
    }

    {
        let mut sum = 0;
        let mut top = BinaryHeap::new();
        for i in 0..n {
            let x = xs[3 * n - 1 - i];
            top.push(x);
            sum += x;
        }
        b[n] = sum;
        for i in 0..n {
            let x = xs[2 * n - 1 - i];
            let y = top.pop().unwrap();
            if x < y {
                sum = sum - y + x;
                top.push(x);
            } else {
                top.push(-y);
            }
            b[n - i - 1] = sum;
        }
    }

    // trace!(xs);
    // trace!(a);
    // trace!(b);
    {
        let mut ans = a[0] - b[0];
        for i in 0..n {
            ans = max(ans, a[i + 1] - b[i + 1]);
        }
        println!("{}", ans);
    }

}

#[allow(dead_code)]
struct Scanner { stdin: io::Stdin, buffer: VecDeque<String>, }
#[allow(dead_code)]
impl Scanner {
    fn new() -> Scanner { Scanner { stdin: io::stdin(), buffer: VecDeque::new() } }
    fn reserve(&mut self) {
        while self.buffer.len() == 0 {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
    }
    fn cin<T: FromStr>(&mut self) -> T {
        self.reserve();
        match self.buffer.pop_front().unwrap().parse::<T>() {
            Ok(a) => a,
            Err(_) => panic!("parse err")
        }
    }
    fn get_char(&mut self) -> char {
        self.reserve();
        let head = self.buffer[0].chars().nth(0).unwrap();
        let tail = String::from( &self.buffer[0][1..] );
        if tail.len()>0 { self.buffer[0]=tail } else { self.buffer.pop_front(); }
        head
    }
}