Problem p03771 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

const int L = 20, N = 201010;

int n, V, x[N], fa[L][N], siz[L][N], ans[N], lt[1 << L], rt[1 << L];
vector<int> v[N];

int Find(int k, int x) {
  return fa[k][x] == x ? x : fa[k][x] = Find(k, fa[k][x]);
}

void Merge(int k, int x, int y) {
  x = Find(k, x), y = Find(k, y);
  fa[k][y] = x;
  siz[k][x] += siz[k][y];
}

int main(void) {
  scanf("%d%d", &n, &V);
  for (int i = 1; i <= n; i++)
    scanf("%d", &x[i]);
  int now = V, m;
  for (int o = L - 1;; now >>= 1, o = (o + 1) % L) {
    for (int i = 1; i <= n; i++)
      fa[o][i] = i, siz[o][i] = 1;
    for (int i = 1; i <= n; i++) {
      int j = i;
      while (j < n && x[j + 1] - x[j] <= now)
        j++;
      for (int k = i + 1; k <= j; k++)
        Merge(o, i, k);
      i = j;
    }
    if (now == 0) {
      m = o + 1;
      break;
    }
  }

  for (int i = 0; i < (1 << m); i++)
    rt[i] = n + 1;
  for (int i = 0; i < (1 << m); i++) {
    for (int j = 0; j < m; j++)
      if (~i >> j & 1) {
        lt[i | (1 << j)] = max(lt[i | (1 << j)], lt[i] + siz[j][lt[i] + 1]);
        rt[i | (1 << j)] = min(rt[i | (1 << j)], Find(j, rt[i] - 1));
        if (Find(j, rt[i] - 1) != rt[i] - siz[j][Find(j, rt[i] - 1)]) {
          assert(0);
        }
      }
  }
  // cerr << lt[27]  <<" " << rt[4] << endl;

  int all = (1 << m) - 1;
  for (int i = 0; i < (1 << m); i++) {
    v[lt[i]].push_back(rt[all ^ i]);
    //    cerr << lt[i] << " " << rt[all ^ i] << endl;
  }

  int mi = n + 2;
  for (int i = 0; i < v[n].size(); i++)
    mi = min(v[n][i], mi);

  for (int i = n; i >= 1; i--) {
    for (int j = 0; j < v[i - 1].size(); j++)
      mi = min(v[i - 1][j], mi);
    if (fa[L - 1][i] != i)
      continue;
    // cerr << i + siz[L - 1][i] << endl;
    ans[i] = mi <= i + siz[L - 1][i];
  }

  for (int i = 1; i <= n; i++)
    puts(ans[Find(L - 1, i)] ? "Possible" : "Impossible");
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const int L = 20, N = 201010;

int n, V, x[N], fa[L][N], siz[L][N], ans[N], lt[1 << L], rt[1 << L];
vector<int> v[N];

int Find(int k, int x) {
  return fa[k][x] == x ? x : fa[k][x] = Find(k, fa[k][x]);
}

void Merge(int k, int x, int y) {
  x = Find(k, x), y = Find(k, y);
  fa[k][y] = x;
  siz[k][x] += siz[k][y];
}

int main(void) {
  scanf("%d%d", &n, &V);
  for (int i = 1; i <= n; i++)
    scanf("%d", &x[i]);
  int now = V, m;
  for (int o = L - 1;; now >>= 1, o = (o + 1) % L) {
    for (int i = 1; i <= n; i++)
      fa[o][i] = i, siz[o][i] = 1;
    for (int i = 1; i <= n; i++) {
      int j = i;
      while (j < n && x[j + 1] - x[j] <= now)
        j++;
      for (int k = i + 1; k <= j; k++)
        Merge(o, i, k);
      i = j;
    }
    if (now == 0) {
      m = o + 1;
      break;
    }
  }

  for (int i = 0; i < (1 << m); i++)
    rt[i] = n + 1;
  for (int i = 0; i < (1 << m); i++) {
    for (int j = 0; j < m; j++)
      if (~i >> j & 1) {
        lt[i | (1 << j)] = max(lt[i | (1 << j)], lt[i] + siz[j][lt[i] + 1]);
        rt[i | (1 << j)] = min(rt[i | (1 << j)], Find(j, rt[i] - 1));
      }
  }
  // cerr << lt[27]  <<" " << rt[4] << endl;

  int all = (1 << m) - 1;
  for (int i = 0; i < (1 << m); i++) {
    v[lt[i]].push_back(rt[all ^ i]);
    //    cerr << lt[i] << " " << rt[all ^ i] << endl;
  }

  int mi = n + 2;
  for (int i = 0; i < v[n].size(); i++)
    mi = min(v[n][i], mi);

  for (int i = n; i >= 1; i--) {
    for (int j = 0; j < v[i - 1].size(); j++)
      mi = min(v[i - 1][j], mi);
    if (fa[L - 1][i] != i)
      continue;
    // cerr << i + siz[L - 1][i] << endl;
    ans[i] = mi <= i + siz[L - 1][i];
  }

  for (int i = 1; i <= n; i++)
    puts(ans[Find(L - 1, i)] ? "Possible" : "Impossible");
  return 0;
}