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

#include <cstdio>
int count[200005];
int a[200005];
long long pow2[200005][2];
long long mod[2], org[2];
int ans[200005];

int popCount(int u) {
  int res = 0;
  while (u != 0) {
    res += u % 2;
    u /= 2;
  }
  return res;
}

void preWork(int n) {
  count[0] = 0;
  for (int i = 1; i <= n; i++) {
    int u = i, cnt = 0;
    while (u) {
      u %= popCount(u);
      cnt++;
    }
    count[i] = cnt;
  }
}

void setUp(int n, int cnt1) {
  mod[0] = cnt1 - 1;
  mod[1] = cnt1 + 1;
  if (mod[0] != 0)
    pow2[0][0] = 1 % mod[0];
  if (mod[1] != 0)
    pow2[0][1] = 1 % mod[1];
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < 2; j++) {
      if (mod[j] <= 0)
        continue;
      pow2[i][j] = pow2[i - 1][j] * 2ll % mod[j];
    }
  }
  org[0] = 0, org[1] = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < 2; j++) {
      if (mod[j] <= 0)
        continue;
      long long cur = pow2[n - i][j];
      if (a[i] != 0)
        org[j] = (org[j] + cur) % mod[j];
    }
  }
}

int main() {
  int n;
  scanf("%d", &n);
  preWork(n);
  int cnt1 = 0;
  for (int i = 1; i <= n; i++) {
    scanf("%1d", &a[i]);
    if (a[i] == 1)
      cnt1++;
  }
  setUp(n, cnt1);
  // printf("ok\\n");
  for (int i = 1; i <= n; i++) {
    if (a[i] == 0) {
      long long cur = org[1];
      cur += pow2[n - i][1];
      if (cur >= mod[1])
        cur -= mod[1];
      // printf("i = %d, cur = %lld\\n",i,cur);
      ans[i] = 1 + count[cur];
    } else {
      if (cnt1 == 1)
        ans[i] = 0;
      else {
        long long cur = org[0];
        cur -= pow2[n - i][0];
        if (cur < 0)
          cur += mod[0];
        // printf("i = %d, cur = %lld\\n",i,cur);
        ans[i] = 1 + count[cur];
      }
    }
  }
  for (int i = 1; i <= n; i++)
    printf("%d\\n", ans[i]);
  return 0;
}


Error: 0

Fixed submission:

#include <cstdio>
int count[200005];
int a[200005];
long long pow2[200005][2];
long long mod[2], org[2];
int ans[200005];

int popCount(int u) {
  int res = 0;
  while (u != 0) {
    res += u % 2;
    u /= 2;
  }
  return res;
}

void preWork(int n) {
  count[0] = 0;
  for (int i = 1; i <= n; i++) {
    int u = i, cnt = 0;
    while (u) {
      u %= popCount(u);
      cnt++;
    }
    count[i] = cnt;
  }
}

void setUp(int n, int cnt1) {
  mod[0] = cnt1 - 1;
  mod[1] = cnt1 + 1;
  pow2[0][0] = 1 % mod[0];
  pow2[0][1] = 1 % mod[1];
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < 2; j++) {
      if (mod[j] <= 0)
        continue;
      pow2[i][j] = pow2[i - 1][j] * 2ll % mod[j];
    }
  }
  org[0] = 0, org[1] = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < 2; j++) {
      if (mod[j] <= 0)
        continue;
      long long cur = pow2[n - i][j];
      if (a[i] != 0)
        org[j] = (org[j] + cur) % mod[j];
    }
  }
}

int main() {
  int n;
  scanf("%d", &n);
  preWork(n);
  int cnt1 = 0;
  for (int i = 1; i <= n; i++) {
    scanf("%1d", &a[i]);
    if (a[i] == 1)
      cnt1++;
  }
  setUp(n, cnt1);
  for (int i = 1; i <= n; i++) {
    if (a[i] == 0) {
      long long cur = org[1];
      cur += pow2[n - i][1];
      if (cur >= mod[1])
        cur -= mod[1];
      // printf("i = %d, cur = %lld\\n",i,cur);
      ans[i] = 1 + count[cur];
    } else {
      if (cnt1 == 1)
        ans[i] = 0;
      else {
        long long cur = org[0];
        cur -= pow2[n - i][0];
        if (cur < 0)
          cur += mod[0];
        // printf("i = %d, cur = %lld\\n",i,cur);
        ans[i] = 1 + count[cur];
      }
    }
  }
  for (int i = 1; i <= n; i++)
    printf("%d\\n", ans[i]);
  return 0;
}