Problem:
Score : 300 points

Problem Statement

You are given an integer sequence of length N. The i-th term in the sequence is a_i.
In one operation, you can select a term and either increment or decrement it by one.

At least how many operations are necessary to satisfy the following conditions?

For every i (1≤i≤n), the sum of the terms from the 1-st through i-th term is not zero.

For every i (1≤i≤n-1), the sign of the sum of the terms from the 1-st through i-th term, is different from the sign of the sum of the terms from the 1-st through (i+1)-th term.

Constraints

2 ≤ n ≤ 10^5

|a_i| ≤ 10^9

Each a_i is an integer.

Input

Input is given from Standard Input in the following format:

n
a_1 a_2 ... a_n

Output

Print the minimum necessary count of operations.

Sample Input 1

4
1 -3 1 0

Sample Output 1

4

For example, the given sequence can be transformed into 1, -2, 2, -2 by four operations. The sums of the first one, two, three and four terms are 1, -1, 1 and -1, respectively, which satisfy the conditions.

Sample Input 2

5
3 -6 4 -5 7

Sample Output 2

0

The given sequence already satisfies the conditions.

Sample Input 3

6
-1 4 3 2 -5 4

Sample Output 3

8

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

#[allow(unused_imports)]
use proconio::input;
#[allow(unused_imports)]
use proconio::marker::Chars;
#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused)]
const ALPHA_SMALL: [char; 26] = [
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
    't', 'u', 'v', 'w', 'x', 'y', 'z',
];
#[allow(unused)]
const ALPHA: [char; 26] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
    'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
];
#[allow(unused)]
fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}
#[allow(unused)]
fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}
#[allow(unused)]
fn read_touple<T: std::str::FromStr + Copy>() -> (T, T) {
    let v: Vec<T> = read_vec();
    assert_eq!(v.len(), 2);
    (v[0], v[1])
}
fn main() {
    input!(N: usize);
    input!(A: [i64; N]);

    let mut ans: i64 = std::i64::MAX;
    for i in 0..2 {
        let mut st = SegmentTree::<i64>::new(&A);
        // i % 2 == 0 ==> 偶数番目が正
        // i % 2 == 1 ==> 偶数番目が負
        let mut tot: i64 = 0;
        for j in 0..N {
            let mut diff = 0;
            let now = st.get(0, j + 1);
            if i % 2 == 0 {
                if j % 2 == 0 && now <= 0 {
                    // 1にする
                    diff = 1 - now;
                } else if j % 2 == 1 && now >= 0 {
                    // -1にする
                    diff = -1 - now;
                }
            } else {
                if j % 2 == 0 && now >= 0 {
                    // -1にする
                    diff = -1 - now;
                } else if j % 2 == 1 && now <= 0 {
                    // 1にする
                    diff = 1 - now;
                }
            }
            //println!("j = {}, now =  {}, diff = {}", j, now, diff);

            tot += diff.abs();
            st.update(j, A[j] + diff);
        }
        ans = min(ans, tot);
    }

    println!("{}", ans);
}

impl Monoid for i64 {
    const E: i64 = 0;
    fn calc(&self, rhs: &i64) -> Self {
        self + rhs
    }
}

#[allow(clippy::declare_interior_mutable_const)]
trait Monoid<Rhs = Self> {
    const E: Rhs;
    fn calc(&self, other: &Rhs) -> Self;
}

#[derive(Debug, PartialEq, Clone)]
struct SegmentTree<T: Clone + Monoid> {
    n: usize, //元の配列に一番近い2の冪乗を格納する
    tree: Vec<T>,
}

// 区間の最小の値を求めるセグメント木
impl<T: Clone + Monoid> SegmentTree<T> {
    // 元の配列をセグメント木で表現
    // 2^nが元の配列のサイズ以上になる最小のnをNとする
    // O(N)
    fn new(v: &[T]) -> SegmentTree<T> {
        let mut n: usize = 1;
        // セグメント木の葉の要素数
        while n < v.len() {
            n *= 2;
        }

        // セグメント木を表現するベクター
        let mut tree = vec![T::E; 2 * n - 1]; // 区間における最小値を求めるセグメント木に注意

        // 葉から順に値を格納していく
        // まず最下段に値を格納する
        for (i, e) in v.iter().enumerate() {
            tree[i + n - 1] = e.clone();
        }

        // 最下段の次の下段から値を書くのしていく
        for i in (0..(n - 1)).rev() {
            tree[i] = T::calc(&tree[2 * i + 1], &tree[2 * i + 2]); // 区間における最小値を求めるセグメント木に注意
        }

        SegmentTree { n, tree }
    }

    // 元の配列のi番目の値が変更された時にセグメント木を更新
    // O(logN) Nは元の配列の長さを超える最小の2の冪乗
    fn update(&mut self, i: usize, val: T) {
        // 最下段の葉を更新
        let mut m = i + self.n - 1;
        self.tree[m] = val;
        while m > 0 {
            m = (m - 1) / 2;
            self.tree[m] = T::calc(&self.tree[2 * m + 1], &self.tree[2 * m + 2]);
            // 区間における最小値を求めるセグメント木に注意
        }
    }

    // 指定された区間の値を求める
    // 区間は半開区間[i, j)での値を求める
    // O(logN)
    fn get(&self, i: usize, j: usize) -> T {
        fn get_sub<U: Clone + Monoid>(
            t: &SegmentTree<U>,
            a: usize,
            b: usize,
            k: usize,
            l: usize,
            r: usize,
        ) -> U {
            // 求めたい区間が今いるノードの対応する区間と交差していない
            if r <= a || b <= l {
                return U::E;
            } // 区間における最小値を求めるセグメント木に注意

            // 求めたい区間が今いるノードの対応する区間を被覆してる
            if a <= l && r <= b {
                return t.tree[k].clone();
            }

            // 求めたい区間と今いるノードと対応している区間が交差してるとき
            // 子を探索する
            // 左の子の値
            let vl = get_sub(t, a, b, 2 * k + 1, l, (l + r) / 2);
            // 右のこの値
            let vr = get_sub(t, a, b, 2 * k + 2, (l + r) / 2, r);

            U::calc(&vl, &vr)
        }

        get_sub(&self, i, j, 0, 0, self.n)
    }
}