Problem p02609 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
#define rep1(i, n) for (ll i = 1; i <= (ll)(n); i++)
#define rep0(i, n) for (ll i = 0; i <= (ll)(n); i++)

ll pow(ll a, ll n) { // compute a^n with o(logn)
  ll res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a;
    a = a * a;
    n >>= 1;
  }
  return res;
}

ll pow(ll a, ll n, ll mod) { // compute a^n (mod mod) with o(logn)
  ll res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

const int MAX = 199;
const int MOD = 1000000007;
ll fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
ll COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

// 順列計算
ll PER(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[n - k] % MOD) % MOD;
}
#define max 200000
int main() {
  ll n;
  string str;
  cin >> n;
  ll pow2_mod[max][2];
  ll x0_mod[2] = {0};
  ll p = 0;

  // input
  cin >> str;
  rep0(i, n - 1) if (str[i] == '1') p++;

  // pre-process
  ll tmp0 = 1 % (p + 1);
  ll tmp1 = 1 % (p - 1);
  rep0(i, max) {
    pow2_mod[i][0] = tmp0;
    pow2_mod[i][1] = tmp1;
    tmp0 *= 2;
    tmp1 *= 2;
    tmp0 %= p + 1;
    tmp1 %= p - 1;
  }
  rep0(i, n - 1) {
    if (str[i] == '1') {
      x0_mod[0] += pow2_mod[n - i - 1][0];
      x0_mod[0] %= p + 1;
      x0_mod[1] += pow2_mod[n - i - 1][1];
      x0_mod[1] %= p - 1;
    }
  }
  rep1(i, n) {
    ll cnt = 1;
    ll tmp;
    if (str[i - 1] == '1')
      tmp = (x0_mod[1] - pow2_mod[n - i][1] + p - 1) % (p - 1);
    else
      tmp = (x0_mod[0] + pow2_mod[n - i][0]) % (p + 1);
    while (tmp > 0) {
      ll pop = 0;
      rep0(i, 19) if (tmp & (1 << i)) pop++;
      tmp %= pop;
      cnt++;
    }
    cout << cnt << endl;
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
#define rep1(i, n) for (ll i = 1; i <= (ll)(n); i++)
#define rep0(i, n) for (ll i = 0; i <= (ll)(n); i++)

ll pow(ll a, ll n) { // compute a^n with o(logn)
  ll res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a;
    a = a * a;
    n >>= 1;
  }
  return res;
}

ll pow(ll a, ll n, ll mod) { // compute a^n (mod mod) with o(logn)
  ll res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

const int MAX = 199;
const int MOD = 1000000007;
ll fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
ll COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

// 順列計算
ll PER(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[n - k] % MOD) % MOD;
}
#define max 200000
int main() {
  ll n;
  string str;
  cin >> n;
  ll pow2_mod[max][2];
  ll x0_mod[2] = {0};
  ll p = 0;

  // input
  cin >> str;
  rep0(i, n - 1) if (str[i] == '1') p++;

  // 例外処理
  if (p == 1) {
    ll tmp0 = 1 % (p + 1);
    rep0(i, max) {
      pow2_mod[i][0] = tmp0;
      tmp0 *= 2;
      tmp0 %= p + 1;
    }
    rep0(i, n - 1) {
      if (str[i] == '1') {
        x0_mod[0] += pow2_mod[n - i - 1][0];
        x0_mod[0] %= p + 1;
      }
    }
    rep1(i, n) {
      ll cnt = 1;
      ll tmp;
      if (str[i - 1] == '1') {
        cout << 0 << endl;
        continue;
      } else {
        tmp = (x0_mod[0] + pow2_mod[n - i][0]) % (p + 1);
        while (tmp > 0) {
          ll pop = 0;
          rep0(i, 19) if (tmp & (1 << i)) pop++;
          tmp %= pop;
          cnt++;
        }
        cout << cnt << endl;
      }
    }
    return 0;
  }

  // pre-process
  ll tmp0 = 1 % (p + 1);
  ll tmp1 = 1 % (p - 1);
  rep0(i, max) {
    pow2_mod[i][0] = tmp0;
    pow2_mod[i][1] = tmp1;
    tmp0 *= 2;
    tmp1 *= 2;
    tmp0 %= p + 1;
    tmp1 %= p - 1;
  }
  rep0(i, n - 1) {
    if (str[i] == '1') {
      x0_mod[0] += pow2_mod[n - i - 1][0];
      x0_mod[0] %= p + 1;
      x0_mod[1] += pow2_mod[n - i - 1][1];
      x0_mod[1] %= p - 1;
    }
  }
  rep1(i, n) {
    ll cnt = 1;
    ll tmp;
    if (str[i - 1] == '1')
      tmp = (x0_mod[1] - pow2_mod[n - i][1] + p - 1) % (p - 1);
    else
      tmp = (x0_mod[0] + pow2_mod[n - i][0]) % (p + 1);
    while (tmp > 0) {
      ll pop = 0;
      rep0(i, 19) if (tmp & (1 << i)) pop++;
      tmp %= pop;
      cnt++;
    }
    cout << cnt << endl;
  }
  return 0;
}