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 C# (Mono 4.6.2.0) (judge verdict: Runtime Error)


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace AtCoder
{
    public class MainClass
    {
        public static void Main(string[] args)
        {
            if (args.Length > 0 && args[0] == "debug")
            {
                var inputs = new[] { @"
3
2 2 4
				", @"
5
3 8 7 5 5
				", @"
3
1000000000 1000000000 0
				" };

                foreach (var str in inputs)
                {
                    var text = str.Trim();
                    if (text.Length == 0) continue;
                    var reader = new System.IO.StringReader(text);
                    Console.SetIn(reader);
                    Main2(args);
                    Console.WriteLine();
                    Console.WriteLine("----------------------------------");
                    Console.WriteLine();
                }
            }
            else
                Main2(args);
        }

        public static void Main2(string[] args)
        {
            checked
            {
                var N = long.Parse(Console.ReadLine());
                var paramsList = Console.ReadLine().Split(' ')
                   .Select(long.Parse)
                   .ToList();

                var a = new double[N, N];
                for (long n = 0; n < N; ++n)
                {
                    a[n, n] = 1;
                    a[n, (n + 1) % N] = 1;
                }

                var c = new double[N, 1];
                for (int n = 0; n < N; n++)
                {
                    c[n, 0] = paramsList[n] * 2;
                }

                var ad = inverseMatrix(a);
                var b = MatrixTimesMatrix(ad, c);

                Console.WriteLine(Enumerable.Range(0, (int)N).Select(n => (long)b[n, 0]).MkString());
            }
        }

        public static double[,] MatrixTimesMatrix(double[,] A, double[,] B)
        {

            double[,] product = new double[A.GetLength(0), B.GetLength(1)];

            for (int i = 0; i < A.GetLength(0); i++)
            {
                for (int j = 0; j < B.GetLength(1); j++)
                {
                    for (int k = 0; k < A.GetLength(1); k++)
                    {
                        product[i, j] += A[i, k] * B[k, j];
                    }
                }
            }

            return product;

        }

        public static double[,] inverseMatrix(double[,] A)
        {

            int n = A.GetLength(0);
            int m = A.GetLength(1);

            double[,] invA = new double[n, m];

            if (n == m)
            {

                int max;
                double tmp;

                for (int j = 0; j < n; j++)
                {
                    for (int i = 0; i < n; i++)
                    {
                        invA[j, i] = (i == j) ? 1 : 0;
                    }
                }

                for (int k = 0; k < n; k++)
                {
                    max = k;
                    for (int j = k + 1; j < n; j++)
                    {
                        if (Math.Abs(A[j, k]) > Math.Abs(A[max, k]))
                        {
                            max = j;
                        }
                    }

                    if (max != k)
                    {
                        for (int i = 0; i < n; i++)
                        {
                            // 入力行列側
                            tmp = A[max, i];
                            A[max, i] = A[k, i];
                            A[k, i] = tmp;
                            // 単位行列側
                            tmp = invA[max, i];
                            invA[max, i] = invA[k, i];
                            invA[k, i] = tmp;
                        }
                    }

                    tmp = A[k, k];

                    for (int i = 0; i < n; i++)
                    {
                        A[k, i] /= tmp;
                        invA[k, i] /= tmp;
                    }

                    for (int j = 0; j < n; j++)
                    {
                        if (j != k)
                        {
                            tmp = A[j, k] / A[k, k];
                            for (int i = 0; i < n; i++)
                            {
                                A[j, i] = A[j, i] - A[k, i] * tmp;
                                invA[j, i] = invA[j, i] - invA[k, i] * tmp;
                            }
                        }
                    }

                }


                //逆行列が計算できなかった時の措置
                for (int j = 0; j < n; j++)
                {
                    for (int i = 0; i < n; i++)
                    {
                        if (double.IsNaN(invA[j, i]))
                        {
                            Console.WriteLine("Error : Unable to compute inverse matrix");
                            invA[j, i] = 0;//ここでは，とりあえずゼロに置き換えることにする
                        }
                    }
                }


                return invA;

            }
            else
            {
                Console.WriteLine("Error : It is not a square matrix");
                return invA;
            }

        }
    }

    public static class EnumerablePlus
    {
        ///<summary>出力文字列に変換。</summary>
        public static string MkString<T>(this IEnumerable<T> list)
        {
            return list.Aggregate(
                new System.Text.StringBuilder(),
                (a, b) => ((a.Length > 0) ? a.Append(' ') : a).Append(b)
                ).ToString();
        }

        ///<summary>添字付きfor。</summary>
        public static void ForEach<T>(this IEnumerable<T> list, Action<T, int> a)
        {
            int i = 0;
            foreach (var item in list)
            {
                a(item, i);
            }
        }

        ///<summary>指定回数デリゲートを呼び出す。</summary>
        public static IEnumerable<T> Repeat<T>(int n, Func<T> f)
        {
            for (int i = 0; i < n; i++)
            {
                yield return f();
            }
        }
    }

    public static class MathPlus
    {
        ///<summary>約数。順番は不定。</summary>
        public static List<long> Divisor(long n)
        {
            var list = Prime(n).
                GroupBy(id => id).
                Select(pair => new { prime = pair.Key, power = pair.Count() }).
                ToList();

            var result = list.Aggregate(new List<long>(), (left, pair) =>
            {
                var list2 = Enumerable.
                    Range(0, pair.power + 1).
                    Aggregate(new List<long>(), (res, l) =>
                    {
                        var next = res.Count > 0 ? res.Last() * pair.prime : 1L;
                        res.Add(next);
                        return res;
                    });

                if (left.Count == 0) return list2.ToList();

                return list2.
                    SelectMany(l => left.Select(m => l * m)).
                    ToList();
            });

            return result;
        }

        ///<summary>順列の数。</summary>
        public static long Permutation(long n, long r)
            => Factorial(n, r);

        ///<summary>組合せの数。</summary>
        public static long Combination(long n, long r)
        {
            if (r == 0) return 1;

            return Factorial(n, r) / Factorial(r);
        }

        ///<summary>階乗。カウントも指定可能。</summary>
        public static long Factorial(long a, long count = long.MaxValue)
        {
            long res = 1;

            for (long i = 0; a > 0 && i < count; i++)
            {
                checked { res *= a; }
                --a;
            }

            return res;
        }

        ///<summary>素因数分解。昇順。</summary>
        public static List<long> Prime(long a)
        {
            var res = new List<long>();

            for (long b = 2, c = (long)Math.Ceiling(Math.Sqrt(a)); b <= c; ++b)
            {
                while (a % b == 0)
                {
                    res.Add(b);
                    a = a / b;
                }
            }

            return res;
        }

        ///<summary>最小公倍数。</summary>
        public static long Lcm(IEnumerable<long> list)
        {
            return list.Aggregate((a, b) => Lcm(a, b));
        }

        ///<summary>最小公倍数。</summary>
        public static long Lcm(long a, long b)
        {
            return checked(a * b) / Gcd(a, b);
        }

        ///<summary>最大公約数。</summary>
        public static long Gcd(IEnumerable<long> list)
        {
            return list.Aggregate((a, b) => Gcd(a, b));
        }

        ///<summary>最大公約数。</summary>
        public static long Gcd(long a, long b)
        {
            if (a < b)
                Gcd(b, a);

            while (b != 0)
            {
                var rem = a % b;
                a = b;
                b = rem;
            }

            return a;
        }
    }
}