Problem p02665 (C++) — buggy submission, verdict: Runtime Error

// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <utility>
#include <vector>

#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

#include <stdexcept>

using namespace std;

// type alias
using ll = long long;
using ull = unsigned long long;
using comp = complex<double>;

const ll MOD = 1000000007LL;
const double PI = 3.14159265358979323846;

// conversion
//------------------------------------------
inline int toint(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class t> inline string tostring(t x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}

// for loop
#define REP(i, n) for ((i) = 0; (i) < (ll)(n); (i)++)

// debug
#define DUMP(x) cerr << #x << " = " << (x) << endl
#define DEBUG(x)                                                               \\
  cerr << #x << " = " << (x) << " (l" << __line__ << ")"                       \\
       << " " << __file__ << endl

template <class Integer> class BinaryIndexedTree {
private:
  ull maxSize_;
  vector<Integer> values_;

public:
  BinaryIndexedTree(ull maxSize) : maxSize_(maxSize), values_(maxSize_, 0) {}

  void update(ll index, Integer increment) {
    if (maxSize_ <= index) {
      throw invalid_argument("Index should be less than maxSize.");
    }
    ++index;

    while (index <= maxSize_) {
      values_[index - 1] += increment;
      index += index & -index;
    }
  }

  Integer query(ll index) {
    if (maxSize_ <= index) {
      throw invalid_argument("Index should be less than maxSize.");
    }
    ++index;

    Integer res = 0;
    while (index > 0) {
      res += values_[index - 1];
      index -= index & -index;
    }
    return res;
  }
};
using bit = BinaryIndexedTree<ll>;

int solve() {
  ll n;
  cin >> n;
  vector<ll> as(n + 1);
  for (ll i = 0; i <= n; ++i) {
    cin >> as[i];
  }

  if (n == 0) {
    if (as[0] == 1) {
      cout << 1 << endl;
      return 0;
    } else {
      cout << -1 << endl;
      return 0;
    }
  }

  bit usable_counts(n * 2 + 1);
  usable_counts.update(0, 2);
  usable_counts.update(1, -2);

  ll curr_using_idx = 0;
  ll res = 1;
  for (ll i = 0; i <= n; ++i) {
    if (as[i] == 0)
      continue;

    ll a = as[i];
    while (a > 0) {
      if (curr_using_idx >= i) {
        cout << -1 << endl;
        return 0;
      }
      ll using_count = min(a, usable_counts.query(curr_using_idx));

      a -= using_count;
      res += (i - curr_using_idx) * using_count;

      usable_counts.update(curr_using_idx, -using_count);
      usable_counts.update(curr_using_idx + 1, using_count * 2LL);
      usable_counts.update(i, -using_count);
      while (curr_using_idx <= n && usable_counts.query(curr_using_idx) == 0) {
        ++curr_using_idx;
      }
    }
  }

  cout << res << endl;

  return 0;
}

// main function
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  solve();

  return 0;
}


Error: 0

Fixed submission:

// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <utility>
#include <vector>

#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

#include <stdexcept>

using namespace std;

// type alias
using ll = long long;
using ull = unsigned long long;
using comp = complex<double>;

const ll MOD = 1000000007LL;
const double PI = 3.14159265358979323846;

// conversion
//------------------------------------------
inline int toint(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class t> inline string tostring(t x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}

// for loop
#define REP(i, n) for ((i) = 0; (i) < (ll)(n); (i)++)

// debug
#define DUMP(x) cerr << #x << " = " << (x) << endl
#define DEBUG(x)                                                               \\
  cerr << #x << " = " << (x) << " (l" << __line__ << ")"                       \\
       << " " << __file__ << endl

template <class Integer> class BinaryIndexedTree {
private:
  ull maxSize_;
  vector<Integer> values_;

public:
  BinaryIndexedTree(ull maxSize) : maxSize_(maxSize), values_(maxSize_, 0) {}

  void update(ll index, Integer increment) {
    if (maxSize_ <= index) {
      throw invalid_argument("Index should be less than maxSize.");
    }
    ++index;

    while (index <= maxSize_) {
      values_[index - 1] += increment;
      index += index & -index;
    }
  }

  Integer query(ll index) {
    if (maxSize_ <= index) {
      throw invalid_argument("Index should be less than maxSize.");
    }
    ++index;

    Integer res = 0;
    while (index > 0) {
      res += values_[index - 1];
      index -= index & -index;
    }
    return res;
  }
};
using bit = BinaryIndexedTree<ll>;

int solve() {
  ll n;
  cin >> n;
  vector<ll> as(n + 1);
  for (ll i = 0; i <= n; ++i) {
    cin >> as[i];
  }

  if (n == 0) {
    if (as[0] == 1) {
      cout << 1 << endl;
    } else {
      cout << -1 << endl;
    }
  }

  bit usable_counts(n * 2 + 1);
  usable_counts.update(0, 2);
  usable_counts.update(1, -2);

  ll curr_using_idx = 0;
  ll res = 1;
  for (ll i = 0; i <= n; ++i) {
    if (as[i] == 0)
      continue;

    ll a = as[i];
    while (a > 0) {
      if (curr_using_idx >= i) {
        cout << -1 << endl;
        return 0;
      }
      ll using_count = min(a, usable_counts.query(curr_using_idx));

      a -= using_count;
      res += (i - curr_using_idx) * using_count;

      usable_counts.update(curr_using_idx, -using_count);
      usable_counts.update(curr_using_idx + 1, using_count * 2LL);
      usable_counts.update(i, -using_count);
      while (curr_using_idx <= n && usable_counts.query(curr_using_idx) == 0) {
        ++curr_using_idx;
      }
    }
  }

  cout << res << endl;

  return 0;
}

// main function
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  solve();

  return 0;
}