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

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <vector>

using namespace std;

int popcount(int n) {
  int count = 0;
  while (n > 0) {
    if (n % 2 == 1) {
      count++;
    }
    n /= 2;
  }
  return count;
}

int f(int n) {
  if (n == 0) {
    return 0;
  }
  return 1 + f(n % popcount(n));
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n;
  cin >> n;
  string x;
  cin >> x;

  const int init_popcount = count(x.begin(), x.end(), '1');
  vector<int> mod_p1(n + 1, 1), mod_m1(n + 1, 1);

  // init_popcount + 1 / init_popcount - 1 で (10 ** i) を割った余りを計算する

  for (int i = 1; i <= n; i++) {
    mod_p1[i] = (mod_p1[i - 1] * 2) % (init_popcount + 1);
    if (init_popcount > 1) {
      mod_m1[i] = (mod_m1[i - 1] * 2) % (init_popcount - 1);
    }
  }

  int init_mod_p1 = 0;
  int init_mod_m1 = 0;
  for (int i = n - 1; i >= 0; i--) {
    if (x[n - 1 - i] == '1') {
      init_mod_p1 += mod_p1[i];
      init_mod_p1 %= (init_popcount + 1);

      if (init_popcount > 1) {
        init_mod_m1 += mod_m1[i];
        init_mod_m1 %= (init_popcount - 1);
      }
    }
  }

  for (int i = n - 1; i >= 0; i--) {
    if (x[n - 1 - i] == '1') {
      const auto mod = init_popcount - 1;
      if (mod == 0) {
        cout << 0 << endl;
      } else {
        const auto init = (init_mod_m1 + (mod - mod_m1[i])) % mod;
        cout << (1 + f(init)) << endl;
      }
    } else {
      const auto mod = init_popcount + 1;
      const auto init = (init_mod_p1 + mod_p1[i]) % mod;
      cout << (1 + f(init)) << endl;
    }
  }

  return 0;
}


Error: 0
popcount: 2
mod_p1[0] = 1
mod_m1[0] = 1
mod_p1[1] = 2
mod_m1[1] = 0
mod_p1[2] = 1
mod_m1[2] = 0
init_mod_p1: 0
init_mod_m1: 0


Fixed submission:

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <vector>

using namespace std;

int popcount(int n) {
  int count = 0;
  while (n > 0) {
    if (n % 2 == 1) {
      count++;
    }
    n /= 2;
  }
  return count;
}

int f(int n) {
  if (n == 0) {
    return 0;
  }
  return 1 + f(n % popcount(n));
}

int main() {
  int n;
  cin >> n;
  string x;
  cin >> x;

  const int init_popcount = count(x.begin(), x.end(), '1');
  vector<int> mod_p1(n + 1, 1), mod_m1(n + 1, 1);

  // init_popcount + 1 / init_popcount - 1 で (10 ** i) を割った余りを計算する
  cerr << "popcount: " << init_popcount << endl;

  for (int i = 1; i <= n; i++) {
    mod_p1[i] = (mod_p1[i - 1] * 2) % (init_popcount + 1);
    mod_m1[i] = (mod_m1[i - 1] * 2) % (init_popcount - 1);
  }

  for (int i = 0; i < n; i++) {
    cerr << "mod_p1[" << i << "] = " << mod_p1[i] << endl;
    cerr << "mod_m1[" << i << "] = " << mod_m1[i] << endl;
  }

  int init_mod_p1 = 0;
  int init_mod_m1 = 0;
  for (int i = n - 1; i >= 0; i--) {
    if (x[n - 1 - i] == '1') {
      init_mod_p1 += mod_p1[i];
      init_mod_p1 %= (init_popcount + 1);

      init_mod_m1 += mod_m1[i];
      init_mod_m1 %= (init_popcount - 1);
    }
  }

  cerr << "init_mod_p1: " << init_mod_p1 << endl;
  cerr << "init_mod_m1: " << init_mod_m1 << endl;

  for (int i = n - 1; i >= 0; i--) {
    if (x[n - 1 - i] == '1') {
      const auto mod = init_popcount - 1;
      if (mod == 0) {
        cout << 0 << endl;
      } else {
        const auto init = (init_mod_m1 + (mod - mod_m1[i])) % mod;
        cout << (1 + f(init)) << endl;
      }
    } else {
      const auto mod = init_popcount + 1;
      const auto init = (init_mod_p1 + mod_p1[i]) % mod;
      cout << (1 + f(init)) << endl;
    }
  }

  return 0;
}