Problem:
Score : 400 points

Problem Statement

There are N mountains in a circle, called Mountain 1, Mountain 2, ..., Mountain N in clockwise order. N is an odd number.

Between these mountains, there are N dams, called Dam 1, Dam 2, ..., Dam N. Dam i (1 \leq i \leq N) is located between Mountain i and i+1 (Mountain N+1 is Mountain 1).

When Mountain i (1 \leq i \leq N) receives 2x liters of rain, Dam i-1 and Dam i each accumulates x liters of water (Dam 0 is Dam N).

One day, each of the mountains received a non-negative even number of liters of rain.

As a result, Dam i (1 \leq i \leq N) accumulated a total of A_i liters of water.

Find the amount of rain each of the mountains received. We can prove that the solution is unique under the constraints of this problem.

Constraints

All values in input are integers.

3 \leq N \leq 10^5-1

N is an odd number.

0 \leq A_i \leq 10^9

The situation represented by input can occur when each of the mountains receives a non-negative even number of liters of rain.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

Print N integers representing the number of liters of rain Mountain 1, Mountain 2, ..., Mountain N received, in this order.

Sample Input 1

3
2 2 4

Sample Output 1

4 0 4

If we assume Mountain 1, 2, and 3 received 4, 0, and 4 liters of rain, respectively, it is consistent with this input, as follows:

Dam 1 should have accumulated \frac{4}{2} + \frac{0}{2} = 2 liters of water.

Dam 2 should have accumulated \frac{0}{2} + \frac{4}{2} = 2 liters of water.

Dam 3 should have accumulated \frac{4}{2} + \frac{4}{2} = 4 liters of water.

Sample Input 2

5
3 8 7 5 5

Sample Output 2

2 4 12 2 8

Sample Input 3

3
1000000000 1000000000 0

Sample Output 3

0 2000000000 0

Solution in Rust (1.42.0) (judge verdict: Runtime Error)

#![allow(unused_imports)]
#![allow(clippy::many_single_char_names)]

// language: Rust(1.42.0)
// check available crates on AtCoder at "https://atcoder.jp/contests/language-test-202001"
// My Library Repo' is at "https://github.com/Loptall/prcn_lib"

/*
    そう甘くはないんだな〜w
*/

// from std...
use std::cmp::{
    max, min, Ordering,
    Ordering::{Equal, Greater, Less},
    Reverse,
};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::convert::TryInto;
use std::mem::swap;
use std::num::{NonZeroU32, ParseIntError};
use std::ops::{
    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
    Index, IndexMut, Mul, MulAssign, Neg, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
    SubAssign,
};
use std::process::exit;
use std::{f32, f64, i128, i16, i32, i64, i8, isize, u128, u16, u32, u64, u8, usize};

// Dep' crates are...
use itertools::*;
use itertools_num::*;
use lazy_static::lazy_static;
use maplit::{btreemap, btreeset, hashmap, hashset};
use num_bigint::{BigInt, BigUint};
use num_complex::Complex;
use num_integer::{binomial, gcd, lcm, multinomial, Integer};
use num_rational::Rational;
use num_traits::{clamp, one, pow, zero, Num, NumAssignOps, NumOps, One, Pow, Zero};
use permutohedron::Heap;
use proconio::{
    fastout, input, is_stdin_empty,
    marker::{Bytes, Chars, Isize1, Usize1},
};
use rand::random;

pub const MOD10E9_7: usize = 1000000007;
pub const MOD99_: usize = 998244353;
pub const MAX: usize = std::usize::MAX;
pub const PI: f64 = f64::consts::PI;
pub const A: u8 = 65;

/// n % m
/// ただし答えが負になる場合は余分にmを足すことで一意な値を保証
///
/// # Panic
/// 異なるmod間での演算をattemptした時
fn compensated_rem(n: i64, m: usize) -> i64 {
    match n % m as i64 {
        r if r >= 0 => r,
        r => r + m as i64,
    }
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Modulo {
    Static(NonZeroU32),
    Dynamic,
}
impl Modulo {
    pub fn get(&self) -> Option<u32> {
        match self {
            Modulo::Static(nz) => Some(nz.get()),
            Modulo::Dynamic => None,
        }
    }
}
/// `ModInt -> PrimiteveInt` への暗黙のキャストは行わない!
/// (get関数を提供するのでそれ使ってどうぞ)
///
/// `PrimitiveInt -> ModInt` は許可する
#[derive(Debug, Clone, Copy)]
pub struct ModInt {
    num: i64,
    _modulo: Modulo,
}
impl Into<usize> for ModInt {
    fn into(self) -> usize {
        self.get() as usize
    }
}
pub trait IntoModInt: Copy {
    fn to_mint<M: TryInto<u32> + Copy>(self, modulo: M) -> ModInt;
}
macro_rules ! impl_into_mint {($ ($ t : ty ) ,* ) => {$ (impl IntoModInt for $ t {fn to_mint < M : TryInto < u32 > + Copy > (self , modulo : M ) -> ModInt {ModInt :: new (self , modulo ) } } ) * } ; }
impl_into_mint!(usize, u8, u16, u32, u64, isize, i8, i16, i32, i64);
impl PartialEq for ModInt {
    fn eq(&self, other: &Self) -> bool {
        if !check_mod_eq(self, other).1 {
            panic!("cannot compare these values because they have different modulo number")
        }
        self.get() == other.num
    }
}
impl PartialOrd for ModInt {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if !check_mod_eq(self, other).1 {
            None
        } else {
            Some(self.get().cmp(&other.num))
        }
    }
}
fn check_mod_eq(a: &ModInt, b: &ModInt) -> (NonZeroU32, bool) {
    match (a._modulo, b._modulo) {
        (Modulo::Static(a), Modulo::Static(b)) => {
            if a == b {
                (a, true)
            } else {
                (unsafe { NonZeroU32::new_unchecked(1) }, false)
            }
        }
        (Modulo::Static(m), Modulo::Dynamic) | (Modulo::Dynamic, Modulo::Static(m)) => (m, true),
        (Modulo::Dynamic, Modulo::Dynamic) => (unsafe { NonZeroU32::new_unchecked(1) }, false),
    }
}
impl ModInt {
    /// always `_modulo > num >= 0 && _modulo >= 1`
    pub fn new<N: TryInto<i64>, M: TryInto<u32> + Copy>(n: N, m: M) -> Self {
        let m = NonZeroU32::new(m.try_into().ok().expect("modulo number may be wrong")).unwrap();
        let r = n
            .try_into()
            .ok()
            .expect("modulo number maybe over i64 range");
        let num = compensated_rem(r, m.get() as usize);
        Self {
            num,
            _modulo: Modulo::Static(m),
        }
    }
    /// get inner value
    pub fn get(&self) -> i64 {
        self.num
    }
    /// mod of modint
    ///
    /// # Panic
    /// if variant is Modulo::Dynamic
    pub fn get_mod(&self) -> usize {
        self._modulo.get().unwrap() as usize
    }
    /// return the power of self with mod, using binary powering method
    /// cannot use of Dynamic type mod Self
    pub fn pow_mod(&self, mut exp: usize) -> Self {
        let mut res = 1;
        let mut base = self.get() as usize;
        let m = self.get_mod();
        while exp > 0 {
            if exp & 1 != 0 {
                res *= base;
                res %= m;
            }
            base *= base;
            base %= m;
            exp >>= 1;
        }
        Self::new(res, self.get_mod())
    }
    /// `a / b == a * b^(-1)` となる `b^(-1)` を求める
    pub fn inv(&self) -> i64 {
        let x = self.get().extended_gcd(&(self.get_mod() as i64)).x;
        compensated_rem(x, self.get_mod())
    }
}
impl Add<Self> for ModInt {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        let c = check_mod_eq(&self, &rhs);
        if !c.1 {
            panic!("modulo between two instance is different!")
        }
        let r = self.get() + rhs.num;
        Self {
            num: if r >= self.get_mod() as i64 {
                r - c.0.get() as i64
            } else {
                r
            },
            _modulo: Modulo::Static(c.0),
        }
    }
}
impl AddAssign<Self> for ModInt {
    fn add_assign(&mut self, rhs: Self) {
        *self = *self + rhs;
    }
}
impl Sub<Self> for ModInt {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        let c = check_mod_eq(&self, &rhs);
        if !c.1 {
            panic!("modulo between two instance is different!")
        }
        let num = compensated_rem(self.get() - rhs.get(), c.0.get() as usize);
        Self {
            num,
            _modulo: Modulo::Static(c.0),
        }
    }
}
impl SubAssign<Self> for ModInt {
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs;
    }
}
impl Mul<Self> for ModInt {
    type Output = Self;
    fn mul(self, rhs: Self) -> Self::Output {
        let c = check_mod_eq(&self, &rhs);
        if !c.1 {
            panic!("modulo between two instance is different!")
        }
        let num = compensated_rem(self.get() * rhs.get(), c.0.get() as usize);
        Self {
            num,
            _modulo: Modulo::Static(c.0),
        }
    }
}
impl MulAssign<Self> for ModInt {
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs
    }
}
impl Div<Self> for ModInt {
    type Output = Self;
    fn div(self, rhs: Self) -> Self::Output {
        let c = check_mod_eq(&self, &rhs);
        if !c.1 {
            panic!("modulo between two instance is different!")
        }
        Self {
            num: self.get() * rhs.inv() % c.0.get() as i64,
            _modulo: Modulo::Static(c.0),
        }
    }
}
impl DivAssign<Self> for ModInt {
    fn div_assign(&mut self, rhs: Self) {
        *self = *self / rhs;
    }
}
impl Rem for ModInt {
    type Output = Self;
    fn rem(self, rhs: Self) -> Self::Output {
        let c = check_mod_eq(&self, &rhs);
        if !c.1 {
            panic!("modulo between two instance is different!")
        }
        Self {
            num: self.num % rhs.num,
            _modulo: Modulo::Static(c.0),
        }
    }
}
impl RemAssign for ModInt {
    fn rem_assign(&mut self, rhs: Self) {
        *self = *self % rhs
    }
}
impl Zero for ModInt {
    fn zero() -> Self {
        ModInt {
            num: 0,
            _modulo: Modulo::Dynamic,
        }
    }
    fn is_zero(&self) -> bool {
        self.num == 0
    }
}
impl One for ModInt {
    fn one() -> Self {
        ModInt {
            num: 1,
            _modulo: Modulo::Dynamic,
        }
    }
    fn is_one(&self) -> bool {
        self.num == 1
    }
}
impl Num for ModInt {
    type FromStrRadixErr = ParseIntError;
    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
        let num = str
            .chars()
            .rev()
            .enumerate()
            .map(|(i, b)| radix.pow(i as u32) as i64 * b.to_digit(radix).unwrap() as i64)
            .sum::<i64>();
        Ok(ModInt {
            num,
            _modulo: Modulo::Dynamic,
        })
    }
}
impl Pow<usize> for ModInt {
    type Output = Self;
    fn pow(mut self, mut exp: usize) -> Self::Output {
        if exp == 0 {
            return Self::one();
        }
        while exp & 1 == 0 {
            self = self * self;
            exp >>= 1;
        }
        if exp == 1 {
            return self;
        }
        let mut acc = self;
        while exp > 1 {
            exp >>= 1;
            self = self * self;
            if exp & 1 == 1 {
                acc = acc * self;
            }
        }
        acc
    }
}
macro_rules ! impl_ops_between_mint_and_primitive {($ ($ t : ty ) ,* ) => {$ (impl Add <$ t > for ModInt {type Output = Self ; fn add (self , rhs : $ t ) -> Self :: Output {self + Self :: new (rhs as i64 , self . get_mod () ) } } impl AddAssign <$ t > for ModInt {fn add_assign (& mut self , rhs : $ t ) {* self = * self + rhs ; } } impl Sub <$ t > for ModInt {type Output = Self ; fn sub (self , rhs : $ t ) -> Self :: Output {self - Self :: new (rhs as i64 , self . get_mod () ) } } impl SubAssign <$ t > for ModInt {fn sub_assign (& mut self , rhs : $ t ) {* self = * self - rhs ; } } impl Mul <$ t > for ModInt {type Output = Self ; fn mul (self , rhs : $ t ) -> Self :: Output {self * Self :: new (rhs as i64 , self . get_mod () ) } } impl MulAssign <$ t > for ModInt {fn mul_assign (& mut self , rhs : $ t ) {* self = * self * rhs ; } } impl Div <$ t > for ModInt {type Output = Self ; fn div (self , rhs : $ t ) -> Self :: Output {self / Self :: new (rhs as i64 , self . get_mod () ) } } impl DivAssign <$ t > for ModInt {fn div_assign (& mut self , rhs : $ t ) {* self = * self / rhs ; } } ) * } ; }
impl_ops_between_mint_and_primitive!(usize, u8, u16, u32, u64, isize, i8, i16, i32, i64);

pub trait PartialBinomialCoefficient {
    fn partial_binomial(&self, n: usize, k: usize) -> Option<ModInt>;
}
pub trait BinomialCoefficient: PartialBinomialCoefficient {
    /// `n C k`
    fn binomial(&self, n: usize, k: usize) -> ModInt {
        self.partial_binomial(n, k).unwrap()
    }
}
/// Binomial Coefficient Table with DP
/// 二項係数を`O(1)`で計算するためのテーブル
///
/// factrial = [1, 1, 2, 6, 24, 120, ...],
///
/// `1 <= k <= n <= 10^7` 程度
pub struct BCTDP {
    _modulo: NonZeroU32,
    factorial: Vec<ModInt>,
    inverse: Vec<ModInt>,
    factorial_inverse: Vec<ModInt>,
}
impl BCTDP {
    /// 初期化
    ///
    /// DPを用いて `O(n log m)`
    /// 割り算を用いるので `log m` がつく
    ///
    /// `1 <= k <= n <= 10^7` 程度
    pub fn new(n: usize, modulo: usize) -> BCTDP {
        let mut factorial = vec![ModInt::new(1, modulo), ModInt::new(1, modulo)];
        factorial.reserve_exact(n);
        let mut inverse = vec![ModInt::new(0, modulo), ModInt::new(1, modulo)];
        inverse.reserve_exact(n);
        let mut factorial_inverse = vec![ModInt::new(1, modulo), ModInt::new(1, modulo)];
        factorial_inverse.reserve_exact(n);
        for i in 2..=n {
            factorial.push(factorial[i - 1] * i);
            inverse.push(modulo.to_mint(modulo) - inverse[modulo % i] * (modulo / i));
            factorial_inverse.push(factorial_inverse[i - 1] * inverse[i]);
        }
        Self {
            _modulo: NonZeroU32::new(modulo as u32).unwrap(),
            factorial,
            inverse,
            factorial_inverse,
        }
    }
    pub fn get_mod(&self) -> usize {
        self._modulo.get() as usize
    }
    pub fn factorial(&self, n: usize) -> ModInt {
        self.factorial[n]
    }
    pub fn factorial_inverse(&self, n: usize) -> ModInt {
        self.factorial_inverse[n]
    }
    /// `n` の mod self._modulo における逆元
    pub fn inv(&self, n: usize) -> ModInt {
        self.inverse[n]
    }
}
impl PartialBinomialCoefficient for BCTDP {
    fn partial_binomial(&self, n: usize, k: usize) -> Option<ModInt> {
        Some(if n < k {
            ModInt::zero()
        } else {
            self.factorial[n] * self.factorial_inverse[k] * self.factorial_inverse[n - k]
        })
    }
}
impl BinomialCoefficient for BCTDP {}
/// `n` が固定値のときに有効
/// `(n(固定値), mod, _[i] = n C i)`
///
/// 初期化: `O(n)`
///
/// `1 <= n <= 10^9 && 1 <= k <= 10^7` 程度
pub struct BCTholdN(usize, NonZeroU32, Vec<ModInt>);
impl BCTholdN {
    pub fn new(mut n: usize, m: usize) -> Self {
        let size = n;
        let mut c = vec![ModInt::new(1, m), ModInt::new(n, m)];
        c.reserve_exact(n + 1);
        for i in 2..=n {
            n -= 1;
            let prev = *c.last().unwrap();
            c.push(prev * n / i);
        }
        Self(size, NonZeroU32::new(m as u32).unwrap(), c)
    }
}
impl PartialBinomialCoefficient for BCTholdN {
    /// #Panic
    ///
    /// self.0 == _n でないとき
    fn partial_binomial(&self, _n: usize, k: usize) -> Option<ModInt> {
        if _n != self.0 {
            None
        } else {
            Some(self.2[k])
        }
    }
}
/// `n, k` の2変数についての `n C k` の表を作る
///
/// `1 <= k <= n <= 2000` 程度
pub struct BCTSmallNK {
    n: usize,
    _modulo: NonZeroU32,
    dp: Vec<Vec<ModInt>>,
}
impl BCTSmallNK {
    pub fn new(n: usize, modulo: usize) -> Self {
        let mut dp = vec![vec![ModInt::new(0, modulo); n + 1]; n + 1];
        dp[0][0] = 1.to_mint(modulo);
        for i in 1..n {
            dp[i][0] = 1.to_mint(modulo);
            for j in 1..n {
                dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
            }
        }
        Self {
            n,
            _modulo: NonZeroU32::new(modulo as u32).unwrap(),
            dp,
        }
    }
    pub fn size(&self) -> usize {
        self.n
    }
    pub fn get_mod(&self) -> usize {
        self._modulo.get() as usize
    }
}
impl PartialBinomialCoefficient for BCTSmallNK {
    fn partial_binomial(&self, n: usize, k: usize) -> Option<ModInt> {
        if n > self.size() || k > self.size() {
            panic!("n or k is too large, compere to dp table!")
        }
        Some(self.dp[n][k])
    }
}
impl BinomialCoefficient for BCTSmallNK {}

/// `n P k` を `O(k)` で
///
/// 内部はfallingをラップしているだけ
pub fn permutation<T: Factoriable>(n: T, k: usize) -> T {
    n.falling(k)
}
pub fn permutation_with_table(table: &BCTDP, n: usize, k: usize) -> ModInt {
    if k > n {
        ModInt::new(0, table.get_mod())
    } else {
        table.factorial(n) * table.factorial_inverse(n - k)
    }
}

pub trait Factoriable: Sized + NumOps + NumAssignOps + Copy + TryInto<usize> {
    fn falling(self, take: usize) -> Self;
    fn rising(self, take: usize) -> Self;
    fn factorial(self) -> Self {
        self.falling(self.try_into().ok().unwrap())
    }
}
macro_rules ! impl_factorialbe {($ ($ t : ty ) ,* ) => {$ (impl Factoriable for $ t {fn falling (self , take : usize ) -> Self {let mut res = Self :: one () ; let mut c = self ; for _ in 0 .. take {res *= c ; c -= Self :: one () ; } res } fn rising (self , take : usize ) -> Self {let mut res = Self :: one () ; let mut c = self ; for _ in 0 .. take {res *= c ; c += 1 ; } res } } ) * } ; }
impl_factorialbe!(usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, ModInt);
pub fn combination(n: ModInt, k: usize) -> ModInt {
    if k > n.get() as usize {
        panic!("n < k, where n in ModInt, k in usize, so cannot calculate n C k")
    }
    permutation(n, k) / k.factorial()
}
pub fn combination_with_table<T: BinomialCoefficient>(table: &T, n: usize, k: usize) -> ModInt {
    table.binomial(n, k)
}

// code...
// #[fastout]
fn main() {
    input! {
        n: usize,
        a: [usize; n]
    }

    let mut ans = binary_search(|x| f(x * 2, &a), 0, 10usize.pow(9) / 2).unwrap() * 2;

    for i in a {
        print!("{} ", ans);
        ans = i * 2 - ans;
    }
    println!();
}

fn f(mut x: usize, a: &Vec<usize>) -> bool {
    let init = x;
    dbg!(x);
    for i in a {
        if x > i * 2 {
            return false;
        }
        x = i * 2 - x;
    }
    x >= init
}

/// # Usage
///
/// `T`は基本的にusizeが入る想定
///
/// `pred`について`l`側が`true`、
/// `r`側が`false`を返すような単調性を持っているとき、
///
/// `pred`を満たす`T`の中で最も大きいものを求める。
///
/// 最初に`l`と`r`について`pred`がそれぞれ`true`、`false`を返すかどうかを調べるので、
/// 範囲は閉空間で指定して良い。
///
/// 返り値`res`は必ず、
///
/// Some(inner) (l <= inner <= r) | None
///
/// になる
///
/// ```rust
/// use prcn_lib::binary_search::binary_search;
///
/// let v = vec![1, 3, 3, 3, 4, 6, 7, 7, 8, 10];
/// assert_eq!(3, binary_search(|i| v[i] < 4, 0, v.len() - 1).unwrap());
/// assert_eq!(9, binary_search(|i| v[i] <= 10, 0, v.len() - 1).unwrap());
/// ```
pub fn binary_search<T, F>(pred: F, l: T, r: T) -> Option<T>
where
    T: Add<Output = T> + Div<Output = T> + PartialEq + Copy + From<u8>,
    F: Fn(T) -> bool,
{
    if !pred(l) {
        return None;
    }
    if pred(r) {
        return Some(r);
    }
    let mut l = l;
    let mut r = r;
    let two = T::from(2);
    loop {
        let m = (l + r) / two;
        if l == m {
            break Some(l);
        }
        if pred(m) {
            l = m;
        } else {
            r = m;
        }
    }
}
/// `v`以上の要素が最初に現れるindex
///
/// ```rust
/// use prcn_lib::binary_search::lower_bound;
///
/// let v: &[i32] = &[1, 3, 3, 4, 5];
/// assert_eq!(lower_bound(v, &0), 0);
/// assert_eq!(lower_bound(v, &1), 0);
/// assert_eq!(lower_bound(v, &2), 1);
/// assert_eq!(lower_bound(v, &3), 1);
/// assert_eq!(lower_bound(v, &4), 3);
/// assert_eq!(lower_bound(v, &5), 4);
/// assert_eq!(lower_bound(v, &999), 5);
/// ```
pub fn lower_bound<T: PartialOrd>(v: &[T], val: &T) -> usize {
    let t = binary_search(|x| v[x] < *val, 0, v.len() - 1);
    match t {
        Some(e) => e + 1,
        None => 0,
    }
}
/// `v`より大きい要素が最初に現れるindex
///
/// ```rust
/// use prcn_lib::binary_search::upper_bound;
///
/// let v: &[i32] = &[1, 3, 3, 4, 5];
/// assert_eq!(upper_bound(v, &0), 0);
/// assert_eq!(upper_bound(v, &1), 1);
/// assert_eq!(upper_bound(v, &2), 1);
/// assert_eq!(upper_bound(v, &3), 3);
/// assert_eq!(upper_bound(v, &4), 4);
/// assert_eq!(upper_bound(v, &5), 5);
/// assert_eq!(upper_bound(v, &999), 5);
/// ```
pub fn upper_bound<T: PartialOrd>(v: &[T], val: &T) -> usize {
    let t = binary_search(|x| v[x] <= *val, 0, v.len() - 1);
    match t {
        Some(e) => e + 1,
        None => 0,
    }
}