Problem:
Score : 600 points

Problem Statement

Given is an integer sequence of length N+1: A_0, A_1, A_2, \ldots, A_N. Is there a binary tree of depth N such that, for each d = 0, 1, \ldots, N, there are exactly A_d leaves at depth d? If such a tree exists, print the maximum possible number of vertices in such a tree; otherwise, print -1.

Notes

A binary tree is a rooted tree such that each vertex has at most two direct children.

A leaf in a binary tree is a vertex with zero children.

The depth of a vertex v in a binary tree is the distance from the tree's root to v. (The root has the depth of 0.)

The depth of a binary tree is the maximum depth of a vertex in the tree.

Constraints

0 \leq N \leq 10^5

0 \leq A_i \leq 10^{8} (0 \leq i \leq N)

A_N \geq 1

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_0 A_1 A_2 \cdots A_N

Output

Print the answer as an integer.

Sample Input 1

3
0 1 1 2

Sample Output 1

7

Below is the tree with the maximum possible number of vertices. It has seven vertices, so we should print 7.

Sample Input 2

4
0 0 1 0 2

Sample Output 2

10

Sample Input 3

2
0 3 1

Sample Output 3

-1

Sample Input 4

1
1 1

Sample Output 4

-1

Sample Input 5

10
0 0 1 1 2 3 5 8 13 21 34

Sample Output 5

264

Solution in C# (.NET Core 3.1.201) (judge verdict: Wrong Answer)

/**
 * code generated by RHelper
 * More info: https://github.com/mkc1370/RHelper
 * @author 
 */

using Task.CFolia;

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

namespace Task.CFolia
{
    public class CFolia
    {
        public void Solve()
        {
            var n = CINL;
            var a = CINVL(n+1);

            var x = 0l;
            var y = 1l;
            var count = 1l;
            var z = new long[n + 1];
            if (a[0] != 0 || a[(int)n] == 0)
            {
                COUT(-1);
                return;
            }

            z[0] = 1;
            for (var i = 1; i < a.Count; i++)
            {
                x = a[i];
                
                if (i < n)
                {
                    if (y * 2 - x - 1 < 0)
                    {
                        COUT(-1);
                        return;
                    }

                    count += y*2;
                }
                else
                {
                    if (y * 2 - x < 0)
                    {
                        COUT(-1);
                        return;
                    }

                    count += y*2;
                }

                y = y * 2 - x;
                z[i] = y;
            }
            z[n] = z[n - 1] * 2;

            var f = z[n] -  a[(int)n];
            for (var i = a.Count - 1; i >= 1; i--)
            {
                count -= f;
                
                if (f <= z[i - 1])
                {
                    break;
                }
                
                f -= z[i - 1];
            }

            COUT(count);
        }
        
        private readonly StringReader cin;
        private readonly StringWriter cout;
        private readonly Scanner scanner;

        public CFolia(StringReader cin, StringWriter cout)
        {
            this.cin = cin;
            this.cout = cout;
            scanner = new Scanner(cin);
        }

        private long CINL => scanner.Long();
        private double CIND => scanner.Double();
        private string CINS => scanner.String();
        private static IEnumerable<T> Repeat<T>(T v, long n) => Enumerable.Repeat(v, (int)n);
        private List<long> CINVL(long n) => Repeat(0, n).Select(_ => CINL).ToList();
        private List<double> CINVD(long n) => Repeat(0, n).Select(_ => CIND).ToList();
        private List<string> CINVS(long n) => Repeat(0, n).Select(_ => CINS).ToList();

        private void COUT(object o) => cout.WriteLine(o);
        
        private void Yes(bool value) => cout.WriteLine(value ? "Yes" : "No");
        private void YES(bool value) => cout.WriteLine(value ? "YES" : "NO");
        private void Possible(bool value) => cout.WriteLine(value ? "Possible" : "Impossible");
        private void POSSIBLE(bool value) => cout.WriteLine(value ? "POSSIBLE" : "IMPOSSIBLE");
    }

    public static class MathEx
    {
        // O (log N)
        public static long Gcd(long n, long m)
        {
            n = Math.Abs(n);
            m = Math.Abs(m);
            while (n != 0)
            {
                m %= n;
                if (m == 0) return n;
                n %= m;
            }

            return m;
        }

        // O (log N)
        public static long Lcm(long n, long m)
        {
            return n / Gcd(n, m) * m;
        }

        // O (N log log N)
        public static bool[] GetPrimeList(int max, List<int> primes = null)
        {
            var isPrime = new bool[max + 1];
            for (var i = 2; i < isPrime.Length; i++) isPrime[i] = true;
            for (var i = 2; i * i <= max; i++)
                if (!isPrime[i]) continue;
                else
                    for (var j = i * i; j <= max; j += i)
                        isPrime[j] = false;
            if (primes != null)
                for (var i = 0; i <= max; i++)
                    if (isPrime[i])
                        primes.Add(i);

            return isPrime;
        }

        // O (N)
        public static T Max<T>(params T[] array) where T : IComparable
        {
            var max = array[0];
            foreach (var value in array)
            {
                if (max.CompareTo(value) < 0)
                    max = value;
            }

            return max;
        }

        // O (N)
        public static T Min<T>(params T[] array) where T : IComparable
        {
            var min = array[0];
            foreach (var value in array)
            {
                if (min.CompareTo(value) > 0)
                    min = value;
            }

            return min;
        }

        public static void Swap<T>(ref T lhs, ref T rhs)
        {
            var temp = lhs;
            lhs = rhs;
            rhs = temp;
        }
    }

    public class Scanner
    {
        public Scanner(StringReader stringReader)
        {
            this.stringReader = stringReader;
        }

        private readonly StringReader stringReader;
        private readonly char[] buffer = new char[1024];
        private int len, ptr;
        private bool isEof;

        private char Read()
        {
            if (isEof) throw new EndOfStreamException();
            if (ptr >= len)
            {
                ptr = 0;
                if ((len = stringReader.Read(buffer, 0, 1024)) <= 0)
                {
                    isEof = true;
                    return '\0';
                }
            }

            return buffer[ptr++];
        }

        public char Char()
        {
            char b;
            do b = Read();
            while (b < 33 || 126 < b);
            return b;
        }

        public string String()
        {
            var sb = new StringBuilder();
            for (char b = Char(); b >= 33 && b <= 126; b = Read())
                sb.Append(b);
            return sb.ToString();
        }

        public long Long()
        {
            long ret = 0;
            char b;
            var ng = false;
            do b = Read();
            while (b != '-' && (b < '0' || '9' < b));
            if (b == '-')
            {
                ng = true;
                b = Read();
            }

            for (;; b = Read())
            {
                if (b < '0' || '9' < b)
                    return ng ? -ret : ret;
                else ret = ret * 10 + b - '0';
            }
        }

        public double Double()
        {
            return double.Parse(String(), CultureInfo.InvariantCulture);
        }
    }

    public struct ModInt {
        public const long Mod = (int)1e9 + 7;

        public long num;
        public ModInt(long n) { num = n; }
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        // O(N log N)
        public static ModInt Pow(long v, long k) {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        // O(log N)
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    public class BinomialCoefficient {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n) {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r] {
            get {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k) {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
}


public class Output
{
	public static void Main()
	{
		var reader = new System.IO.StringReader(Console.In.ReadToEnd());
		var writer = new System.IO.StringWriter();
		var solver = new CFolia(reader, writer);
		solver.Solve();
		System.Console.Write(writer.GetStringBuilder().ToString());
	}
}