Problem p02652 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define llint long long
#define inf 1e18
#define rep(x, s, t) for (llint(x) = (s); (x) < (t); (x)++)
#define Rep(x, s, t) for (llint(x) = (s); (x) <= (t); (x)++)
#define chmin(x, y) (x) = min((x), (y))
#define chmax(x, y) (x) = max((x), (y))

using namespace std;
typedef pair<llint, llint> P;

struct BIT {
  int size;
  vector<llint> bit;
  BIT() { size = 0; }
  BIT(int s) {
    size = s;
    bit.resize(size + 1);
    init();
  }
  void init() {
    for (int i = 1; i <= size; i++)
      bit[i] = 0;
  }
  llint query(int i) {
    llint ret = 0;
    while (i > 0) {
      ret += bit[i];
      i -= i & (-i);
    }
    return ret;
  }
  void add(int i, llint x) {
    while (i <= size) {
      bit[i] += x;
      i += i & (-i);
    }
  }
};

string s;
BIT bit(1000005);

void update(llint p, llint x) {
  llint v = bit.query(p), d = x - v;
  bit.add(p, d), bit.add(p + 1, -d);
}

llint get(llint l, llint r) {
  llint ub = r + 1, lb = l - 1, mid;
  while (ub - lb > 1) {
    mid = (ub + lb) / 2;
    llint res = bit.query(mid);
    if (res > 0) {
      if (res > inf / 2) {
        if (bit.query(mid + 1) > 0 || bit.query(mid - 1) > 0)
          lb = mid;
        else
          ub = mid;
      } else
        lb = mid;
    } else
      ub = mid;
  }
  return lb;
}

int main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);

  cin >> s;
  llint n = s.size();
  s = "#" + s;

  bit.add(1, inf);
  update(1000002, 0);

  llint l = 1000002, r = 1000002, k = 1000002;
  for (int i = 1; i <= n; i++) {
    if (s[i] == '0') {
      llint res = get(l, r);
      // cout << res << endl;
      if (res >= l)
        bit.add(l, -1), bit.add(res + 1, 1);
      l--;
      update(l, inf);
    }
    if (s[i] == '1') {
      bit.add(l, 1), bit.add(r + 1, -1);
      l++;
      llint x = min(bit.query(l - 1), bit.query(l));
      update(l, x);
      update(l - 1, inf);
    }
    if (s[i] == '?') {
      if (l == k) {
        llint x = min(bit.query(k), bit.query(k + 1)) + 1;
        llint res = get(l, r);
        // cout << "!" << res << endl;
        if (res >= l)
          bit.add(l, -1), bit.add(res + 1, 1);
        l--;
        k--;
        update(k, x);
      } else {
        llint x = bit.query(k + 1) + 1, y = bit.query(k) + 1;
        llint res = get(l, r);
        if (res >= l)
          bit.add(l, -1), bit.add(res + 1, 1);
        l--;
        k -= 2;
        update(k, y), update(k + 1, x);
      }
    }
    k = max(l, k);
    // for(int i = l; i <= r; i++) cout << bit.query(i) << " "; cout << endl;
  }

  llint ans = inf;
  for (int i = l; i <= r; i++) {
    ans = min(ans, bit.query(i) + (i - l));
  }
  cout << ans << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define llint long long
#define inf 1e18
#define rep(x, s, t) for (llint(x) = (s); (x) < (t); (x)++)
#define Rep(x, s, t) for (llint(x) = (s); (x) <= (t); (x)++)
#define chmin(x, y) (x) = min((x), (y))
#define chmax(x, y) (x) = max((x), (y))

using namespace std;
typedef pair<llint, llint> P;

struct BIT {
  int size;
  vector<llint> bit;
  BIT() { size = 0; }
  BIT(int s) {
    size = s;
    bit.resize(size + 1);
    init();
  }
  void init() {
    for (int i = 1; i <= size; i++)
      bit[i] = 0;
  }
  llint query(int i) {
    llint ret = 0;
    while (i > 0) {
      ret += bit[i];
      i -= i & (-i);
    }
    return ret;
  }
  void add(int i, llint x) {
    while (i <= size) {
      bit[i] += x;
      i += i & (-i);
    }
  }
};

string s;
BIT bit(1000005);

void update(llint p, llint x) {
  llint v = bit.query(p), d = x - v;
  bit.add(p, d), bit.add(p + 1, -d);
}

llint get(llint l, llint r) {
  llint ub = r + 1, lb = l - 1, mid;
  while (ub - lb > 1) {
    mid = (ub + lb) / 2;
    llint res = bit.query(mid);
    if (res > 0) {
      if (res > inf / 2) {
        if (bit.query(mid + 1) > 0 || bit.query(mid - 1) > 0)
          lb = mid;
        else
          ub = mid;
      } else
        lb = mid;
    } else
      ub = mid;
  }
  return lb;
}

int main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);

  cin >> s;
  llint n = s.size();
  s = "#" + s;

  bit.add(1, inf);
  update(1000002, 0);

  llint l = 1000002, r = 1000002, k = 1000002;
  for (int i = 1; i <= n; i++) {
    if (s[i] == '0') {
      llint res = get(l, r);
      // cout << res << endl;
      if (res >= l)
        bit.add(l, -1), bit.add(res + 1, 1);
      l--;
      update(l, inf);
    }
    if (s[i] == '1') {
      bit.add(l, 1), bit.add(r + 1, -1);
      if (l < r)
        l++;
      llint x = min(bit.query(l - 1), bit.query(l));
      update(l, x);
      update(l - 1, inf);
    }
    if (s[i] == '?') {
      if (l == k) {
        llint x = min(bit.query(k), bit.query(k + 1)) + 1;
        llint res = get(l, r);
        // cout << "!" << res << endl;
        if (res >= l)
          bit.add(l, -1), bit.add(res + 1, 1);
        l--;
        k--;
        update(k, x);
      } else {
        llint x = bit.query(k + 1) + 1, y = bit.query(k) + 1;
        llint res = get(l, r);
        if (res >= l)
          bit.add(l, -1), bit.add(res + 1, 1);
        l--;
        k -= 2;
        update(k, y), update(k + 1, x);
      }
    }
    k = max(l, k);
    // for(int i = l; i <= r; i++) cout << bit.query(i) << " "; cout << endl;
  }

  llint ans = inf;
  for (int i = l; i <= r; i++) {
    ans = min(ans, bit.query(i) + (i - l));
  }
  cout << ans << endl;

  return 0;
}