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

#include <iostream>
#include <string>
#define MAX 200000
using namespace std;

/*
popcount(n)
f(n) = n%popcount(n)が0になるまで
*/

long long n;
string X;

void f(long long k, long long n) {

  if (n == 0)
    cout << k << endl;
  else {
    // cは1の個数
    long long m = n, c = 0;
    while (m) {
      c += m & 1;
      m >>= 1;
    }
    if (c == 0) {
      cout << k << endl;
      return;
    }
    f(k + 1, n % c);
  }
}

int main() {

  cin >> n;
  cin >> X;

  long long num = 0;

  // 1の数を数える
  for (int i = 0; i < n; i++) {
    if (X[i] == '1')
      num++;
  }

  long long x[MAX], y[MAX], z[MAX], b = 1;

  x[n - 1] = 1 % num;
  y[n - 1] = 1 % (num + 1);
  if (num - 1 != 0) {
    z[n - 1] = 1 % (num - 1);
  }

  for (int i = n - 2; i >= 0; i--) {
    // i桁目が1だったときの mod num + 1
    y[i] = (2 * y[i + 1]) % (num + 1);
    // i桁目が1だったときの mod num - 1
    if (num - 1 != 0) {
      z[i] = (2 * z[i + 1]) % (num - 1);
    }
  }

  // mod num + 1のときの値
  long long ans1 = 0;
  for (int j = 0; j < X.size(); j++) {
    if (X[j] == '1')
      ans1 = (ans1 + y[j]) % (num + 1);
  }

  // mod num - 1のときの値
  long long ans2 = 0;
  if (num - 1 != 0) {

    for (int j = 0; j < X.size(); j++) {
      if (X[j] == '1')
        ans2 = (ans2 + z[j]) % (num - 1);
    }
  }

  for (int i = 0; i < n; i++) {

    string s;
    long long mod = num;
    long long c = 0;
    s = X;
    if (X[i] == '0') {
      s[i] = '1';
      mod++;

      c = (ans1 + y[i]) % mod;
    }
    if (X[i] == '1') {
      s[i] = '0';
      mod--;
      if (mod != 0) {
        c = (ans2 - z[i] + mod) % mod;
      }
    }

    if (mod <= 0) {
      cout << "0" << endl;
    } else if (c != 0) {
      f(1, c);
    } else {
      cout << "1" << endl;
    }
  }

  return 0;
}

Error: 0

Fixed submission:

#include <iostream>
#include <string>
#define MAX 200000
using namespace std;

/*
popcount(n)
f(n) = n%popcount(n)が0になるまで
*/

long long n;
string X;

void f(long long k, long long n) {
  if (n == 0)
    printf("%d\\n", k);
  // if(c == 0) printf()
  else {
    // cは1の個数
    long long m = n, c = 0;
    while (m) {
      c += m & 1;
      m >>= 1;
    }
    f(k + 1, n % c);
  }
}

int main() {

  cin >> n;
  cin >> X;

  long long num = 0;

  // 1の数を数える
  for (int i = 0; i < n; i++) {
    if (X[i] == '1')
      num++;
  }

  long long x[MAX], y[MAX], z[MAX], b = 1;

  x[n - 1] = 1 % num;
  y[n - 1] = 1 % (num + 1);
  z[n - 1] = 1 % (num - 1);

  for (int i = n - 2; i >= 0; i--) {
    // i桁目が1だったときの mod num + 1
    y[i] = (2 * y[i + 1]) % (num + 1);
    // i桁目が1だったときの mod num - 1
    z[i] = (2 * z[i + 1]) % (num - 1);
  }

  // mod num + 1のときの値
  long long ans1 = 0;
  for (int j = 0; j < X.size(); j++) {
    if (X[j] == '1')
      ans1 = (ans1 + y[j]) % (num + 1);
  }

  // mod num - 1のときの値
  long long ans2 = 0;
  for (int j = 0; j < X.size(); j++) {
    if (X[j] == '1')
      ans2 = (ans2 + z[j]) % (num - 1);
  }

  for (int i = 0; i < n; i++) {

    string s;
    long long mod = num;
    long long c = 0;
    s = X;
    if (X[i] == '0') {
      s[i] = '1';
      mod++;

      c = (ans1 + y[i]) % mod;
    }
    if (X[i] == '1') {
      s[i] = '0';
      mod--;

      c = (ans2 - z[i] + mod) % mod;
    }

    if (mod <= 0) {
      cout << "1" << endl;
    } else if (c != 0) {

      f(1, c);
    } else {
      cout << "1" << endl;
    }
  }

  return 0;
}