Problem:
Score: 200 points

Problem Statement

Takahashi, who works at DISCO, is standing before an iron bar.
The bar has N-1 notches, which divide the bar into N sections. The i-th section from the left has a length of A_i millimeters.

Takahashi wanted to choose a notch and cut the bar at that point into two parts with the same length.
However, this may not be possible as is, so he will do the following operations some number of times before he does the cut:

Choose one section and expand it, increasing its length by 1 millimeter. Doing this operation once costs 1 yen (the currency of Japan).

Choose one section of length at least 2 millimeters and shrink it, decreasing its length by 1 millimeter. Doing this operation once costs 1 yen.

Find the minimum amount of money needed before cutting the bar into two parts with the same length.

Constraints

2 \leq N \leq 200000

1 \leq A_i \leq 2020202020

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 A_3 ... A_N

Output

Print an integer representing the minimum amount of money needed before cutting the bar into two parts with the same length.

Sample Input 1

3
2 4 3

Sample Output 1

3

The initial lengths of the sections are [2, 4, 3] (in millimeters). Takahashi can cut the bar equally after doing the following operations for 3 yen:

Shrink the second section from the left. The lengths of the sections are now [2, 3, 3].

Shrink the first section from the left. The lengths of the sections are now [1, 3, 3].

Shrink the second section from the left. The lengths of the sections are now [1, 2, 3], and we can cut the bar at the second notch from the left into two parts of length 3 each.

Sample Input 2

12
100 104 102 105 103 103 101 105 104 102 104 101

Sample Output 2

0

Solution in Rust (1.15.1) (judge verdict: Accepted)

//  ____            _                  _                       _       _
// |  _ \ _   _ ___| |_    ___ _ __   | |_ ___ _ __ ___  _ __ | | __ _| |_ ___
// | |_) | | | / __| __|  / __| '_ \  | __/ _ \ '_ ` _ \| '_ \| |/ _` | __/ _ \
// |  _ <| |_| \__ \ |_  | (__| |_) | | ||  __/ | | | | | |_) | | (_| | ||  __/
// |_| \_\\__,_|___/\__|  \___| .__/___\__\___|_| |_| |_| .__/|_|\__,_|\__\___|
//                            |_| |_____|               |_|

//https://github.com/manta1130/Competitive_Programming_Template_Rust

#[macro_use]
mod input {

    use std;
    use std::io;

    const SPLIT_DELIMITER: char = ' ';

    #[macro_export]
    #[allow(unused_macros)]
    macro_rules! input {
    ( $($x:expr ),*) => {
        {
            let temp_str = input_line_str();
            let mut split_result_iter = temp_str.split_whitespace();
                $(
                let buf_split_result = split_result_iter.next();
                let buf_split_result = buf_split_result.unwrap();
                    ($x) = buf_split_result.parse().unwrap();
                )*
        }
    };
}

    #[allow(dead_code)]
    pub fn input_line_str() -> String {
        let mut s = String::new();
        io::stdin().read_line(&mut s).unwrap();
        s.trim().to_string()
    }

    #[allow(dead_code)]
    pub fn p<T>(t: T)
    where
        T: std::fmt::Display,
    {
        println!("{}", t);
    }

    #[allow(dead_code)]
    pub fn input_vector2d<T>(line: usize) -> Vec<Vec<T>>
    where
        T: std::str::FromStr,
    {
        let mut v: Vec<Vec<T>> = Vec::new();

        for _ in 0..line {
            let vec_line = input_vector();
            v.push(vec_line);
        }
        v
    }

    #[allow(dead_code)]
    pub fn input_vector<T>() -> Vec<T>
    where
        T: std::str::FromStr,
    {
        let mut v: Vec<T> = Vec::new();

        let s = input_line_str();
        let split_result = s.split(SPLIT_DELIMITER);
        for z in split_result {
            let buf = match z.parse() {
                Ok(r) => r,
                Err(_) => panic!("Parse Error"),
            };
            v.push(buf);
        }
        v
    }

    #[allow(dead_code)]
    pub fn input_vector_row<T>(n: usize) -> Vec<T>
    where
        T: std::str::FromStr,
    {
        let mut v = Vec::with_capacity(n);
        for _ in 0..n {
            let buf = match input_line_str().parse() {
                Ok(r) => r,
                Err(_) => panic!("Parse Error"),
            };
            v.push(buf);
        }
        v
    }

    pub trait ToCharVec {
        fn to_charvec(&self) -> Vec<char>;
    }

    impl ToCharVec for String {
        fn to_charvec(&self) -> Vec<char> {
            self.to_string().chars().collect::<Vec<_>>()
        }
    }
}
mod vectools {
pub fn upper_bound<T>(v: &Vec<T>, k: T) -> usize
where
    T: PartialOrd,
{
    let mut from = 0;
    let mut to = v.len();

    while to - from > 1 {
        let mid = (from + to) / 2;
        if v[mid] <= k {
            from = mid;
        } else {
            to = mid;
        }
    }
    if v[from] > k {
        from
    } else {
        to
    }
}

///C++のlower_boundと同等の実装
pub fn lower_bound<T>(v: &Vec<T>, k: T) -> usize
where
    T: PartialOrd,
{
    let mut from = 0;
    let mut to = v.len();

    while to - from > 1 {
        let mid = (from + to) / 2;
        if v[mid] < k {
            from = mid;
        } else {
            to = mid;
        }
    }

    if v[from] < k {
        to
    } else {
        from
    }
}

///次の順列を求める。
pub fn next_permutation<T>(v: &mut Vec<T>) -> bool
where
    T: PartialOrd,
{
    let mut pivot = v.len() - 1;
    loop {
        if pivot == 0 {
            return false;
        }
        if v[pivot] > v[pivot - 1] {
            pivot -= 1;
            break;
        }
        pivot -= 1;
    }
    let mut pivot_swap = v.len() - 1;
    while v[pivot] >= v[pivot_swap] {
        pivot_swap -= 1;
    }
    v.swap(pivot, pivot_swap);
    v[pivot + 1..].reverse();
    true
}

}

use input::*;
use vectools::*;

fn main() {
    let n: usize;
    input!(n);
    let mut a = input_vector::<usize>();

    let mut table = vec![];
    let mut sum = 0;
    for i in &a {
        sum += i * 2;
        table.push(sum);
    }
    sum /= 2;

    let s = lower_bound(&table, sum);
    if table[s] == sum {
        p(0);
        return;
    }

    let mut ans = usize::max_value();
    if s != 0 {
        ans = (sum - table[s - 1]);
    }
    if s < table.len() {
        ans = std::cmp::min(ans, (table[s] - sum));
    }
    p(ans);
}