#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<unordered_map>
#include<cmath>
#include <bits/stdc++.h>



#define  ll long long int
#define REP(i,n) for(int i=0;i<n;i++)
#define v(T,n) vector<T>n
#define YES cout<<"YES"<<endl;
#define Yes cout<<"Yes"<<endl;
#define NO cout<<"NO"<<endl;
#define No cout<<"No"<<endl;
#define null NULL
#define D cout<<"Debug"<<endl;

using namespace std;
const ll MOD = 1000000007;
const ll MAX = 65565;
ll fac[MAX], finv[MAX], inv[MAX];
using Graph = vector<vector<int>>;

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
//--------------------------------------bfs------------------------------------------
	
vector<int> dist;//for bfs
queue<int> que;
	
void bfs(int N, Graph G){
	/* in main, read data
	
	int N,M;
	cin>>N>>M;
	Graph G(N);
    for (int i = 0; i < M; ++i) {
        int a, b;
        cin >> a >> b;
		a-=1;b-=1;
        G[a].push_back(b);
        G[b].push_back(a);
    }
	bfs(N,G);
	
	*/
  // BFS のためのデータ構造
	dist.assign(N,-1);
	
    // 初期条件 (頂点 0 を初期ノードとする)
    dist[0] = 0;
    que.push(0); // 0 を橙色頂点にする

    // BFS 開始 (キューが空になるまで探索を行う)
 while (!que.empty()) {  
        int v = que.front(); // キューから先頭頂点を取り出す
        que.pop();

        // v から辿れる頂点をすべて調べる
        for (int nv : G[v]) {
            if (dist[nv] != -1) continue; // すでに発見済みの頂点は探索しない

            // 新たな白色頂点 nv について距離情報を更新してキューに追加する
            dist[nv] = dist[v] + 1;
            que.push(nv);
        }
    }
}
//--------------------------------------bfs------------------------------------------
//--------------------------------------dfs------------------------------------------
vector<bool> seen;
void dfs(const Graph &G, int v) {
	/*
	int N, M; 
	cin >> N >> M;

    Graph G(N);
    for (int i = 0; i < M; ++i) {
        int a, b;
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }


    seen.assign(N, false); // 全頂点を「未訪問」に初期化
    dfs(G, 0);
	
	*/
    seen[v] = true; // v を訪問済にする

    // v から行ける各頂点 next_v について
    for (auto next_v : G[v]) { 
        if (seen[next_v]) continue; // next_v が探索済だったらスルー
        dfs(G, next_v); // 再帰的に探索
    }
}
	
//--------------------------------------dfs------------------------------------------

//--------------------------------------a^n------------------------------------------

ll modpow(ll a, ll  n) { //二分累乗法 a^n
    ll ret = 1;
    while (n > 0) {
        if (n & 1) ret = ret * a % MOD;
        a = a * a % MOD;
        n >>= 1;
    }
    return ret;
}
//-------------------------------------a^n------------------------------------------

//--------------------------------------COM nCk------------------------------------------
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++){
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

ll COM(int n, int k){ //nCk
//use COMinit() before use this.
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
//--------------------------------------COM nCk------------------------------------------
//-------------------------------------binary search-----------------------------------------
bool isOK(int index, int key, vector<int>& binary_A) {
    if (binary_A[index] >= key) return true;
    else return false;
}

// 汎用的な二分探索のテンプレ
int binary_search(int key, vector<int>& binary_A) {
      int ng = -1; //「index = 0」が条件を満たすこともあるので、初期値は -1
    int ok = (int)binary_A.size(); // 「index = a.size()-1」が条件を満たさないこともあるので、初期値は a.size()

    /* ok と ng のどちらが大きいかわからないことを考慮 */
    while (abs(ok - ng) > 1) {
        int mid = (ok + ng) / 2;

        if (isOK(mid, key,binary_A)) ok = mid;
        else ng = mid;
    }
    return ok;
}
//-------------------------------------binary search-------------------------------------
//---------------------------------------sort-----------------------------------------
void upper_sort(vector<int>& vec_A){
	sort(vec_A.begin(), vec_A.end());
}
void lower_sort(vector<int>& vec_A){
	sort(vec_A.begin(), vec_A.end(), std::greater<int>() );
}
//---------------------------------------sort-----------------------------------------
void Main()
{
	int N;
	cin>>N;
	vector<ll> A(100010);
	ll max_nodes = 0;
	REP(i,N+1){
		cin>>A[i];
		max_nodes += A[i];
	}
	
	ll nodes=1;
	ll ans = 0;
	REP(i,N+1){
		
		if(A[i] > nodes){
			cout<<"-1"<<endl;
			return;
		}else if(A[i] == nodes){
			if(i == N){
				cout<<ans+1<<endl;
				return;
			}else{
				cout<<"-1"<<endl;
				return;
			}
		}
		nodes-=A[i];
		max_nodes -= A[i];
	
		nodes = min(max_nodes, nodes*2);
		ans += nodes;
	}
	cout<<ans+1<<endl;
	return;
}

int main()
{
	std::cin.tie(nullptr);
	std::ios_base::sync_with_stdio(false);
	std::cout << std::fixed << std::setprecision(15);
	COMinit();
	Main();
}

Measured memory_bytes: 5588