Problem p00952 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <iostream>
using namespace std;

const int depth = 19;
class Segtree {
  int sum[1 << (depth + 1)];

public:
  Segtree() {
    for (int i = 0; i < 1 << (depth + 1); i++) {
      sum[i] = 0;
    }
  }

  void update(int pos, int x) { // x=0,1
    pos += (1 << depth) - 1;
    int plus = x - sum[pos];

    sum[pos] += plus;
    while (pos > 0) {
      pos = (pos - 1) / 2;
      sum[pos] += plus;
    }
  }

  //??????[l, r)??????
  int getSum(int l, int r, int a = 0, int b = (1 << depth), int id = 0) {
    if (l >= b || r <= a) {
      return 0;
    }
    if (l <= a && b <= r) {
      return sum[id];
    }
    int u = getSum(l, r, a, a + (b - a) / 2, id * 2 + 1);
    int v = getSum(l, r, a + (b - a) / 2, b, id * 2 + 2);
    return u + v;
  }

  //????????????(0????????????)??\\?????§, ??????????????????0?????????
  int getZeroPos(int a = 0, int b = (1 << depth), int id = 0) {
    if (sum[id] == b - a || id == (1 << depth) - 1) {
      return (1 << depth);
    }
    if (b - a == 1) {
      return id - (1 << depth) + 1;
    }
    int u = getZeroPos(a, a + (b - a) / 2, id * 2 + 1);
    if (u != (1 << depth)) {
      return u;
    }
    return getZeroPos(a + (b - a) / 2, b, id * 2 + 2);
  }
};

int n;
int x[500000];
int s[500100]; // s[0].s[1]s[2]???
Segtree seg;

bool check(int digit) {
  if (s[0] == 1) {
    return false;
  }

  int pos = seg.getZeroPos();
  if (digit >= pos) {
    return true;
  }
  if (digit < pos - 1) {
    return false;
  }
  if (seg.getSum(pos, (1 << depth)) > 0) {
    return false;
  }
  return true;
}

void addBit(int digit) {
  if (digit > n + 90) {
    return;
  }

  s[digit]++;
  seg.update(digit, s[digit]);

  for (int i = digit; i > 0 && s[i] == 2; i--) {
    s[i - 1]++;
    seg.update(i - 1, s[i - 1]);
    s[i] = 0;
    seg.update(i, 0);
  }
}

void print() {
  cout << "s = " << s[0] << ".";
  for (int i = 1; i < 10; i++) {
    cout << s[i];
  }
  cout << endl;
}

int main() {
  int i;

  cin >> n;
  for (i = 0; i < n; i++)
    cin >> x[i];

  for (i = 0; i < n; i++) {
    if (!check(x[i])) {
      cout << "No" << endl;
    } else {
      cout << "Yes" << endl;
      addBit(x[i]);
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
using namespace std;

const int depth = 19;
class Segtree {
  int sum[1 << (depth + 1)];

public:
  Segtree() {
    for (int i = 0; i < 1 << (depth + 1); i++) {
      sum[i] = 0;
    }
  }

  void update(int pos, int x) { // x=0,1
    pos += (1 << depth) - 1;
    int plus = x - sum[pos];

    sum[pos] += plus;
    while (pos > 0) {
      pos = (pos - 1) / 2;
      sum[pos] += plus;
    }
  }

  //??????[l, r)??????
  int getSum(int l, int r, int a = 0, int b = (1 << depth), int id = 0) {
    if (l >= b || r <= a) {
      return 0;
    }
    if (l <= a && b <= r) {
      return sum[id];
    }
    int u = getSum(l, r, a, a + (b - a) / 2, id * 2 + 1);
    int v = getSum(l, r, a + (b - a) / 2, b, id * 2 + 2);
    return u + v;
  }

  //????????????(0????????????)??\\?????§, ??????????????????0?????????
  int getZeroPos(int a = 0, int b = (1 << depth), int id = 0) {
    if (sum[id] == b - a || id == (1 << depth) - 1) {
      return (1 << depth);
    }
    if (b - a == 1) {
      return id - (1 << depth) + 1;
    }
    int u = getZeroPos(a, a + (b - a) / 2, id * 2 + 1);
    int v = getZeroPos(a + (b - a) / 2, b, id * 2 + 2);
    return min(u, v);
  }
};

int n;
int x[500000];
int s[500100]; // s[0].s[1]s[2]???
Segtree seg;

bool check(int digit) {
  if (s[0] == 1) {
    return false;
  }

  int pos = seg.getZeroPos();
  if (digit >= pos) {
    return true;
  }
  if (digit < pos - 1) {
    return false;
  }
  if (seg.getSum(pos, (1 << depth)) > 0) {
    return false;
  }
  return true;
}

void addBit(int digit) {
  if (digit > n + 90) {
    return;
  }

  s[digit]++;
  seg.update(digit, s[digit]);
  for (int i = digit; i > 0 && s[i] == 2; i--) {
    s[i - 1]++;
    seg.update(i - 1, s[i - 1]);
    s[i] = 0;
    seg.update(i, 0);
  }
}

void print() {
  cout << "s = " << s[0] << ".";
  for (int i = 1; i < 10; i++) {
    cout << s[i];
  }
  cout << endl;
}

int main() {
  int i;

  cin >> n;
  for (i = 0; i < n; i++)
    cin >> x[i];

  for (i = 0; i < n; i++) {
    if (!check(x[i])) {
      cout << "No" << endl;
    } else {
      cout << "Yes" << endl;
      addBit(x[i]);
    }
  }
  return 0;
}