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

// 7/10
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (ll i = 0; i < (n); ++i)
using ll = long long;
using P = pair<int, int>;

ll f[300010];

// int pow2(int t, int mod) {
//     if (t == 0) return 1;
//     int a = pow(t/2, mod);
//     a *= a;
//     a %= mod;
//     if (t%2==1) a *= 2;
//     a %= mod;
//     if (a < 0) a = (a + mod) % mod;
//     return a;
// }

ll pow2(ll t, ll mod) {
  if (t == 0)
    return 1;
  ll a = pow2(t / 2, mod);
  a = a * a;
  a %= mod;
  if (t % 2 == 1)
    a *= 2;
  a %= mod;
  return a;
}

int main() {
  ll N;
  string X;
  cin >> N >> X;

  f[0] = 0;
  for (ll i = 1; i < 300000; i++) {
    ll now = i % (ll)__builtin_popcount(i);
    f[i] = 1 + f[now];
  }

  // rep(i, 11) {
  //     printf("f[%d] = %d\\n", i, f[i]);
  // }

  // rep(i, 11) {
  //     printf("pow(%d, %d) = %d\\n", i, 12, pow2(i, 12));
  // }

  ll first_pop_count = 0;
  ll first_mod_plus = 0;
  ll first_mod_minus = 0;

  rep(i, N) {
    if (X[i] == '1')
      first_pop_count++;
  }

  ll digit = 1;
  rep(i, N) {
    ll ri = N - 1 - i;
    if (X[ri] == '1') {
      first_mod_plus += digit;
      first_mod_plus %= (first_pop_count + 1);
      // first_mod_minus += digit;
      // first_mod_minus %= (first_pop_count - 1);
    }
    digit *= 2;
    digit %= (first_pop_count + 1);
  }

  digit = 1;
  if (first_pop_count > 1) {
    rep(i, N) {
      ll ri = N - 1 - i;
      if (X[ri] == '1') {
        // first_mod_plus += digit;
        // first_mod_plus %= (first_pop_count + 1);
        first_mod_minus += digit;
        first_mod_minus %= (first_pop_count - 1);
      }
      digit *= 2;
      digit %= (first_pop_count - 1);
    }
  }

  rep(i, N) {
    ll ri = N - 1 - i;
    ll now;
    if (X[i] == '1') {
      // ri桁目が1から0になった時のf(X)を求める
      if (first_pop_count == 1) {
        cout << 0 << endl;
      } else {
        now = first_mod_minus - pow2(ri, first_pop_count - 1);
        now %= (first_pop_count - 1);
        if (now < 0)
          now = (now + first_pop_count - 1) % (first_pop_count - 1);
        cout << 1 + f[now] << endl;
      }
    } else {
      // ri桁目が0から1になった時のf(X)を求める
      now = first_mod_plus + pow2(ri, first_pop_count + 1);
      // now = (now + first_pop_count + 1) % (first_pop_count + 1);
      now %= (first_pop_count + 1);
      if (now < 0)
        now = (now + first_pop_count + 1) % (first_pop_count + 1);
      cout << 1 + f[now] << endl;
    }
  }
}

Error: 0

Fixed submission:

// 7/10
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (ll i = 0; i < (n); ++i)
using ll = long long;
using P = pair<int, int>;

ll f[300010];

// int pow2(int t, int mod) {
//     if (t == 0) return 1;
//     int a = pow(t/2, mod);
//     a *= a;
//     a %= mod;
//     if (t%2==1) a *= 2;
//     a %= mod;
//     if (a < 0) a = (a + mod) % mod;
//     return a;
// }

ll pow2(ll t, ll mod) {
  if (t == 0)
    return 1;
  ll a = pow2(t / 2, mod);
  a = a * a;
  a %= mod;
  if (t % 2 == 1)
    a *= 2;
  a %= mod;
  return a;
}

int main() {
  ll N;
  string X;
  cin >> N >> X;

  f[0] = 0;
  for (ll i = 1; i < 300000; i++) {
    ll now = i % (ll)__builtin_popcount(i);
    f[i] = 1 + f[now];
  }

  // rep(i, 11) {
  //     printf("f[%d] = %d\\n", i, f[i]);
  // }

  // rep(i, 11) {
  //     printf("pow(%d, %d) = %d\\n", i, 12, pow2(i, 12));
  // }

  ll first_pop_count = 0;
  ll first_mod_plus = 0;
  ll first_mod_minus = 0;

  rep(i, N) {
    if (X[i] == '1')
      first_pop_count++;
  }

  ll digit = 1;
  rep(i, N) {
    ll ri = N - 1 - i;
    if (X[ri] == '1') {
      first_mod_plus += digit;
      first_mod_plus %= (first_pop_count + 1);
      // first_mod_minus += digit;
      // first_mod_minus %= (first_pop_count - 1);
    }
    digit *= 2;
    digit %= (first_pop_count + 1);
  }

  digit = 1;
  rep(i, N) {
    ll ri = N - 1 - i;
    if (X[ri] == '1') {
      // first_mod_plus += digit;
      // first_mod_plus %= (first_pop_count + 1);
      first_mod_minus += digit;
      first_mod_minus %= (first_pop_count - 1);
    }
    digit *= 2;
    digit %= (first_pop_count - 1);
  }

  rep(i, N) {
    ll ri = N - 1 - i;
    ll now;
    if (X[i] == '1') {
      // ri桁目が1から0になった時のf(X)を求める
      if (first_pop_count == 1) {
        cout << 0 << endl;
      } else {
        now = first_mod_minus - pow2(ri, first_pop_count - 1);
        now %= (first_pop_count - 1);
        if (now < 0)
          now = (now + first_pop_count - 1) % (first_pop_count - 1);
        cout << 1 + f[now] << endl;
      }
    } else {
      // ri桁目が0から1になった時のf(X)を求める
      now = first_mod_plus + pow2(ri, first_pop_count + 1);
      // now = (now + first_pop_count + 1) % (first_pop_count + 1);
      now %= (first_pop_count + 1);
      if (now < 0)
        now = (now + first_pop_count + 1) % (first_pop_count + 1);
      cout << 1 + f[now] << endl;
    }
  }
}