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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <string>
#include <vector>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
const int iINF = 1001001001;
const long long llINF = 1LL << 60;
ll repPow(ll x, ll n, ll m) {
  // x^n % mを高速に求めるアルゴリズム
  if (n == 0)
    return 1;
  if (n % 2 == 0)
    return repPow(x * x % m, n / 2, m);
  else
    return x * repPow(x, n - 1, m) % m;
}
int getDigit(int i) {
  int dig = 0;
  while (i != 0) {
    i /= 2;
    dig++;
  }
  return dig;
}
int pcnt(int x) {
  int d = getDigit(x);
  int cnt = 0;
  rep(i, d) {
    if (x >> i & 1)
      cnt++;
  }
  return cnt;
}
int f(int x) {
  if (x == 0)
    return 0;
  return f(x % pcnt(x)) + 1;
}
int main() {
  ll n;
  string s;
  cin >> n >> s;
  vector<int> x(n);
  rep(i, n) x[i] = s[i] - '0';
  int pc = 0;
  rep(i, n) pc += x[i];
  vector<int> ans(n);
  rep(b, 2) {
    // b == 0 : 0 → 1に変更
    // b == 1 : 1 → 0に変更
    int npc = pc;
    if (b == 0)
      npc++;
    else
      npc--;
    if (npc <= 0)
      continue; // npc == 0の時は必ずans == 0. また,
                // 0徐算が起こるためcontinueする.
    // 変更前の値(mod npc)を求めておく
    int r0 = 0;
    rep(i, n) {
      r0 = (r0 * 2) % npc;
      r0 += x[i];
    }
    // r0に変更分を足し引きする
    // kを計算しやすくするために下の桁から計算していく
    int k = 1;
    for (int i = n - 1; i >= 0; --i) {
      if (x[i] == b) {
        int r = r0;
        if (b == 0)
          r = (r + k) % npc;
        else
          r = (r - k + npc) % npc; // ()内が負にならないようにnpcを足す
        ans[i] = f(r) + 1;
      }
      k = (k * 2) % npc;
    }
  }
  rep(i, n) cout << ans[i] << endl;
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <string>
#include <vector>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
const int iINF = 1001001001;
const long long llINF = 1LL << 60;
ll repPow(ll x, ll n, ll m) {
  // x^n % mを高速に求めるアルゴリズム
  if (n == 0)
    return 1;
  if (n % 2 == 0)
    return repPow(x * x % m, n / 2, m);
  else
    return x * repPow(x, n - 1, m) % m;
}
int main() {
  const int len = 200000;
  ll n;
  string x;
  cin >> n >> x;
  ll pc = 0;
  rep(i, n) {
    if (x[i] == '1')
      pc++;
  }
  vector<ll> pow2_minus(n, 0);
  vector<ll> pow2_plus(n, 0);
  rep(i, n) {
    pow2_minus[i] = repPow(2, i, pc - 1);
    pow2_plus[i] = repPow(2, i, pc + 1);
    pow2_minus[i] %= pc - 1;
    pow2_plus[i] %= pc + 1;
  }
  ll xmod_minus = 0;
  ll xmod_plus = 0;
  rep(i, n) {
    if (x[i] == '1') {
      xmod_minus += pow2_minus[n - 1 - i];
      xmod_plus += pow2_plus[n - 1 - i];
      xmod_minus %= pc - 1;
      xmod_plus %= pc + 1;
    }
  }
  vector<ll> ans(n, 1);
  rep(i, n) {
    ll m;
    ll modpc;
    if (x[i] == '0') {
      modpc = pc + 1;
      m = xmod_plus;
      m += pow2_plus[n - 1 - i];
      m %= modpc;
    } else {
      modpc = pc - 1;
      m = xmod_minus;
      m -= pow2_minus[n - 1 - i];
      m %= modpc;
      if (m < 0)
        m += modpc;
    }
    while (m != 0) {
      bitset<len> b(m);
      modpc = b.count();
      m %= modpc;
      ans[i]++;
    }
  }
  rep(i, n) cout << ans[i] << endl;
  return 0;
}