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

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;

const ll MX = 1e18;
int n;
ll d[64];

ll coun(ll l, int k) {
  // k-th bit of [0, l)
  return (1LL << k) * (l / (1LL << (k + 1))) +
         max(0LL, (l % (1LL << (k + 1))) - (1LL << k));
}

int check(ll l, ll r) {
  ll d1[150] = {}, d2[150] = {};
  for (int i = 0; i < n; i++) {
    d1[i] = d[i];
    d2[i] = coun(r, i) - coun(l, i);
    //        printf("%d %lld %lld\\n", i, d1[i], d2[i]);
  }
  ll of = 0;
  for (int i = 0; i < 150; i++) {
    ll nof = (d1[i] + of) / 2;
    d1[i] = (d1[i] + of) % 2;
    of = nof;
  }
  of = 0;
  for (int i = 0; i < 150; i++) {
    ll nof = (d2[i] + of) / 2;
    d2[i] = (d2[i] + of) % 2;
    of = nof;
  }
  assert(!d1[149] and !d2[149]);
  for (int i = 149; i >= 0; i--) {
    if (d1[i] < d2[i])
      return 1;
    if (d2[i] < d1[i])
      return -1;
  }
  return 0;
}

int c = 0;
ll a, b;

void calc1() {
  b = (1LL << (n - 1)) + d[n - 1];
  ll l = 0, r = (1LL << (n - 1));
  while (r - l > 1) {
    ll md = (l + r) / 2;
    int f = 0;
    assert(d[n - 1] == coun(b, n - 1) - coun(md, n - 1));
    for (int i = 0; i < n - 1; i++) {
      ll x = coun(b, i) - coun(md, i);
      if (x < d[i]) {
        f = -1;
        break;
      }
      if (d[i] < x) {
        f = 1;
        break;
      }
    }
    if (f == 0) {
      a = md;
      b--;
      //            printf("find1: %lld %lld\\n", a, b);
      if (b <= MX)
        c++;
      break;
    }
    if (f == -1) {
      r = md;
    } else {
      l = md;
    }
  }
}
void calc2() {
  ll l = (1LL << (n - 1)) - 1, r = (1LL << n) + 1 - d[n - 1];
  while (r - l > 1) {
    ll md = (l + r) / 2;
    assert(d[n - 1] == coun(md + d[n - 1], n - 1) - coun(md, n - 1));
    int f = check(md, md + d[n - 1]);
    if (f == 0) {
      if (md + d[n - 1] - 1 <= MX) {
        a = md;
        b = md + d[n - 1] - 1;
        //                printf("find2: %lld %lld\\n", a, b);
        c++;
      }
      break;
    }
    if (f == -1) {
      l = md;
    } else {
      r = md;
    }
  }
}
void solve2() {
  assert(2 <= n and n <= 60);
  if ((1LL << (n - 1)) < d[n - 1]) {
    cout << "None" << endl;
    return;
  }
  c = 0;
  calc1();
  calc2();
  if (!c) {
    cout << "None" << endl;
  } else if (2 <= c) {
    cout << "Many" << endl;
  } else {
    cout << a << " " << b << endl;
  }
}

bool solve() {
  scanf("%d", &n);
  if (!n)
    return false;
  fill_n(d, 64, 0);
  bool f = false;
  for (int i = 0; i < n; i++) {
    scanf("%lld", d + i);
    if (MX < d[i]) {
      f = true;
    }
  }
  if (f) {
    cout << "None" << endl;
    return true;
  }
  while (n && !d[n - 1])
    n--;
  if (n == 0 or 61 <= n) {
    //        printf("%d\\n", n);
    cout << "None" << endl;
  } else if (n == 1) {
    if (d[0] == 1) {
      cout << "1 1" << endl;
    } else {
      cout << "None" << endl;
    }
  } else {
    solve2();
  }
  return true;
}

int main() {
  while (solve()) {
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;

const ll MX = 1e18;
int n;
ll d[64];

ll coun(ll l, int k) {
  // k-th bit of [0, l)
  return (1LL << k) * (l / (1LL << (k + 1))) +
         max(0LL, (l % (1LL << (k + 1))) - (1LL << k));
}
int c = 0;
ll a, b;

void calc1() {
  b = (1LL << (n - 1)) + d[n - 1];
  ll l = 0, r = (1LL << (n - 1));
  while (r - l > 1) {
    ll md = (l + r) / 2;
    int f = 0;
    assert(d[n - 1] == coun(b, n - 1) - coun(md, n - 1));
    for (int i = 0; i < n - 1; i++) {
      ll x = coun(b, i) - coun(md, i);
      if (x < d[i]) {
        f = -1;
        break;
      }
      if (d[i] < x) {
        f = 1;
        break;
      }
    }
    if (f == 0) {
      a = md;
      b--;
      //            printf("find1: %lld %lld\\n", a, b);
      if (b <= MX)
        c++;
      break;
    }
    if (f == -1) {
      r = md;
    } else {
      l = md;
    }
  }
}
void calc2() {
  ll l = (1LL << (n - 1)) - 1, r = (1LL << n) + 1 - d[n - 1];
  while (r - l > 1) {
    ll md = (l + r) / 2;
    int f = 0;
    for (int i = n - 1; i >= 0; i--) {
      ll x = coun(md + d[n - 1], i) - coun(md, i);
      if (x < d[i]) {
        f = -1;
        break;
      }
      if (d[i] < x) {
        f = 1;
        break;
      }
    }
    if (f == 0) {
      a = md;
      b = md + d[n - 1] - 1;
      //            printf("find2: %lld %lld\\n", a, b);
      if (b <= MX)
        c++;
      break;
    }
    if (f == -1) {
      l = md;
    } else {
      r = md;
    }
  }
}
void solve2() {
  assert(2 <= n and n <= 60);
  if ((1LL << (n - 1)) < d[n - 1]) {
    cout << "None" << endl;
    return;
  }
  c = 0;
  calc1();
  calc2();
  if (!c) {
    cout << "None" << endl;
  } else if (2 <= c) {
    cout << "Many" << endl;
  } else {
    cout << a << " " << b << endl;
  }
}

bool solve() {
  cin >> n;
  if (!n)
    return false;
  fill_n(d, 64, 0);
  for (int i = 0; i < n; i++) {
    cin >> d[i];
    if (MX < d[i]) {
      cout << "None" << endl;
      return true;
    }
  }
  while (n && !d[n - 1])
    n--;
  if (n == 0 or 61 <= n) {
    //        printf("%d\\n", n);
    cout << "None" << endl;
  } else if (n == 1) {
    if (d[0] == 1) {
      cout << "1 1" << endl;
    } else {
      cout << "None" << endl;
    }
  } else {
    solve2();
  }
  return true;
}

int main() {
  while (solve()) {
  }
  return 0;
}