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

#include <bits/stdc++.h>
#define _GLIBCXX_DEBUG
using namespace std;
using ll = long long;
using vec = vector<ll>;
using vect = vector<double>;
using Graph = vector<vector<ll>>;
#define loop(i, n) for (ll i = 0; i < n; i++)
#define Loop(i, m, n) for (ll i = m; i < n; i++)
#define pool(i, n) for (ll i = n; i >= 0; i--)
#define Pool(i, m, n) for (ll i = n; i >= m; i--)
#define mod 1000000007ll
#define flagcount __builtin_popcount
#define flag(x) (1 << x)
#define flagadd(bit, x) bit |= flag(x)
#define flagpop(bit, x) bit &= ~flag(x)
#define flagon(bit, i) bit &flag(i)
#define flagoff(bit, i) !(bit & (1 << i))
#define all(v) v.begin(), v.end()
#define low2way(v, x) lower_bound(all(v), x)
#define high2way(v, x) upper_bound(all(v), x)
#define idx_lower(v, x)                                                        \\
  (distance(v.begin(), low2way(v, x))) // 配列vでx未満の要素数を返す
#define idx_upper(v, x)                                                        \\
  (distance(v.begin(), high2way(v, x))) // 配列vでx以下の要素数を返す
#define idx_lower2(v, x)                                                       \\
  (v.size() - idx_lower(v, x)) // 配列vでx以上の要素数を返す
#define idx_upper2(v, x)                                                       \\
  (v.size() - idx_upper(v, x)) // 配列vでxより大きい要素の数を返す
#define putout(a) cout << a << endl
#define Gput(a, b) G[a].push_back(b)
#define Sum(v) accumulate(all(v), 0ll)
#define gcd(x, y) __gcd(x, y)
ll ctoi(char c) {
  if (c >= '0' && c <= '9') {
    return c - '0';
  }
  return 0;
}
template <typename T> T lcm(T x, T y) {
  T z = gcd(x, y);
  return x * y / z;
}
template <typename T> bool primejudge(T n) {
  if (n < 2)
    return false;
  else if (n == 2)
    return true;
  else if (n % 2 == 0)
    return false;
  double sqrtn = sqrt(n);
  for (T i = 3; i < sqrtn + 1; i++) {
    if (n % i == 0) {
      return false;
    }
    i++;
  }
  return true;
}
// 場合によって使い分ける
// const ll dx[4]={1,0,-1,0};
// const ll dy[4]={0,1,0,-1};
const ll dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
const ll dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
// 2次元配列の宣言
// vector<vector<ll>> field(h, vector<ll>(w));

int main() {
  cout << fixed << setprecision(30);
  ll N;
  string X;
  cin >> N >> X;
  ll pp = 0;
  loop(i, N) if (X[i] == '1') pp++;
  // 後に2桁ある前提でloopを回すためコーナーケースとなる
  if (N == 1) {
    if (pp == 0)
      putout(1);
    else
      putout(0);
    return 0;
  }
  // pp=0の場合、ビット反転後1で割ったあまりは0であるため、絶対に回数は1になる
  if (pp == 0) {
    loop(i, N) putout(1);
    return 0;
  }
  // pp=1のとき、そのビットを反転したときのみ答えは0
  // それ以外の時はpp=2となるが、普通あまりは0となる。(2つの2冪の和であるため)
  // コーナーケースは、X[N-1]=='1'のとき
  if (pp == 1) {
    if (X[N - 1] == '1') {
      loop(i, N - 1) putout(2);
      putout(0);
      return 0;
    }
    ll ind = 0;
    loop(i, N) if (X[i] == '1') {
      ind = i;
      break;
    }
    loop(i, N) {
      if (i != N - 1) {
        if (i != ind)
          putout(1);
        else
          putout(0);
      } else
        putout(2);
    }
    return 0;
  }
  // 後は通常のケースを求めるのみ
  vec amariminus(N),
      amariplus(
          N); // amari[i]:「左」から見たときに2冪をpp±1で割ったときのあまり
  ll preminus = 0, preplus = 0;
  amariminus[0] = 1;
  amariplus[0] = 1;
  Loop(i, 1, N) {
    amariminus[i] = (amariminus[i - 1] * 2) % (pp - 1);
    amariplus[i] = (amariplus[i - 1] * 2) % (pp + 1);
  }
  // ここで配列を逆転させる
  reverse(all(amariminus));
  reverse(all(amariplus));
  loop(i, N) {
    char now = X[i];
    if (now == '1') {
      preminus += amariminus[i];
      preminus %= (pp - 1);
      preplus += amariplus[i];
      preplus %= (pp + 1);
    }
  }
  // f(0)~f(200000)を求める
  vec dp(200001);
  dp[0] = 0;
  dp[1] = 1;
  Loop(i, 2, 200001) {
    ll count = 0;
    ll now = i;
    while (now > 0) {
      if (now % 2 == 1)
        count++;
      now /= 2;
    }
    ll x = i;
    dp[x] = dp[x % count] + 1;
  }
  loop(i, N) {
    ll ans = 1;
    char now = X[i];
    if (now == '1') {
      ll Q = preminus;
      Q -= amariminus[i];
      if (Q < 0)
        Q += (pp - 1);
      Q %= (pp - 1);
      ans += dp[Q];
      putout(ans);
    } else {
      ll Q = preplus;
      Q += amariplus[i];
      Q %= (pp + 1);
      ans += dp[Q];
      putout(ans);
    }
  }
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define _GLIBCXX_DEBUG
using namespace std;
using ll = long long;
using vec = vector<ll>;
using vect = vector<double>;
using Graph = vector<vector<ll>>;
#define loop(i, n) for (ll i = 0; i < n; i++)
#define Loop(i, m, n) for (ll i = m; i < n; i++)
#define pool(i, n) for (ll i = n; i >= 0; i--)
#define Pool(i, m, n) for (ll i = n; i >= m; i--)
#define mod 1000000007ll
#define flagcount __builtin_popcount
#define flag(x) (1 << x)
#define flagadd(bit, x) bit |= flag(x)
#define flagpop(bit, x) bit &= ~flag(x)
#define flagon(bit, i) bit &flag(i)
#define flagoff(bit, i) !(bit & (1 << i))
#define all(v) v.begin(), v.end()
#define low2way(v, x) lower_bound(all(v), x)
#define high2way(v, x) upper_bound(all(v), x)
#define idx_lower(v, x)                                                        \\
  (distance(v.begin(), low2way(v, x))) // 配列vでx未満の要素数を返す
#define idx_upper(v, x)                                                        \\
  (distance(v.begin(), high2way(v, x))) // 配列vでx以下の要素数を返す
#define idx_lower2(v, x)                                                       \\
  (v.size() - idx_lower(v, x)) // 配列vでx以上の要素数を返す
#define idx_upper2(v, x)                                                       \\
  (v.size() - idx_upper(v, x)) // 配列vでxより大きい要素の数を返す
#define putout(a) cout << a << endl
#define Gput(a, b) G[a].push_back(b)
#define Sum(v) accumulate(all(v), 0ll)
#define gcd(x, y) __gcd(x, y)
ll ctoi(char c) {
  if (c >= '0' && c <= '9') {
    return c - '0';
  }
  return 0;
}
template <typename T> T lcm(T x, T y) {
  T z = gcd(x, y);
  return x * y / z;
}
template <typename T> bool primejudge(T n) {
  if (n < 2)
    return false;
  else if (n == 2)
    return true;
  else if (n % 2 == 0)
    return false;
  double sqrtn = sqrt(n);
  for (T i = 3; i < sqrtn + 1; i++) {
    if (n % i == 0) {
      return false;
    }
    i++;
  }
  return true;
}
// 場合によって使い分ける
// const ll dx[4]={1,0,-1,0};
// const ll dy[4]={0,1,0,-1};
const ll dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
const ll dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
// 2次元配列の宣言
// vector<vector<ll>> field(h, vector<ll>(w));

int main() {
  cout << fixed << setprecision(30);
  ll N;
  string X;
  cin >> N >> X;
  ll defaultcount = 0;
  loop(i, N) if (X[i] == '1')
      defaultcount++; // ここからpopcount(Xi)は±1しか変わらない
  // とりあえずもとのf(X)をもとめてみる
  vector<ll> amari(N), amari1(N), amari2(N);
  amari[0] = 1 % defaultcount;
  amari1[0] = 1 % (defaultcount - 1);
  amari2[0] = 1 % (defaultcount + 1);
  Loop(i, 1, N) {
    amari[i] = (amari[i - 1] * 2) % defaultcount;
    amari1[i] = (amari1[i - 1] * 2) % (defaultcount - 1);
    amari2[i] = (amari2[i - 1] * 2) % (defaultcount + 1);
  }
  ll ffX = 0, ffX1 = 0, ffX2 = 0;
  loop(i, N) {
    if (X[i] == '1') {
      ffX += amari[N - 1 - i];
      ffX %= defaultcount;
      ffX1 += amari1[N - 1 - i];
      ffX1 %= (defaultcount - 1);
      ffX2 += amari2[N - 1 - i];
      ffX2 %= (defaultcount + 1);
    }
  }
  ll fX = 1;
  // ここで、f(1)~f(400000)まで求めてみる
  vec dp(400001);
  dp[0] = 0;
  dp[1] = 1;
  Loop(i, 2, 400001) {
    ll now = i;
    ll pp = 0;
    while (now > 0) {
      if (now % 2 == 1)
        pp++;
      now /= 2;
    }
    dp[i] = dp[i % pp] + 1;
  }
  fX += dp[ffX];
  loop(i, N) {
    ll nowX;
    ll pp = defaultcount;
    if (X[i] == '0') {
      pp++; // 1になるので
      nowX = ffX2;
      nowX += amari2[N - 1 - i];
      ll ans = 1;
      ans += dp[nowX];
      putout(ans);
    } else {
      nowX = ffX1;
      pp--;
      if (pp == 0) {
        putout(0);
        continue;
      }
      nowX -= amari1[N - 1 - i];
      if (nowX <= 0)
        nowX += pp;
      ll ans = 1;
      ans += dp[nowX % pp];
      putout(ans);
    }
  }
  return 0;
}