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

#include <bits/stdc++.h>
#include <iostream>
using namespace std;

int startx[2000000];

#define _LL long long

int modpow(int a, int b, int m) {
  _LL prebit = a % m;
  _LL ans = 1;
  for (int bit = 0; (long unsigned int)b >= (1UL << bit); bit++) {
    if (bit > 0)
      prebit = (prebit * prebit) % m;
    if (b & (1UL << bit))
      ans = (ans * prebit) % m;
  }
  return ans;
}

// x <= n
int calcf(int x) {
  if (x == 0)
    return 0;
  int popcount = 0;
  for (int i = 0; (1 << i) <= x; i++) {
    if ((1 << i) & x)
      popcount++;
  }
  return calcf(x % popcount) + 1;
}

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

  _LL popcount = 0;
  for (int i = 0; i < n; i++) {
    startx[i] = (s[i] == '1' ? 1 : 0);
    if (startx[i] == 1)
      popcount++;
  }
  _LL mod0 = 0;
  if (popcount > 1) {
    // popcount - 1でxをわったときのあまりを求める
    for (int i = 0; i < n; i++) {
      mod0 = (mod0 * 2) % (popcount - 1);
      if (startx[i] == 1)
        mod0 = (mod0 + 1) % (popcount - 1);
    }
  }
  _LL mod1 = 0;
  for (int i = 0; i < n; i++) {
    mod1 = (mod1 * 2) % (popcount + 1);
    if (startx[i] == 1)
      mod1 = (mod1 + 1) % (popcount + 1);
  }

  for (_LL i = 0; i < n; i++) {
    _LL nmod = 0;
    if (startx[i] == 1) {
      // 1 -> 0
      if (popcount - 1 > 0) {
        nmod = (mod0 - modpow(2, n - 1 - i, popcount - 1)) % (popcount - 1);
        if (nmod < 0)
          nmod += popcount - 1;
      } else {
        cout << 0 << endl;
        continue;
      }
    } else {
      nmod = (mod1 + modpow(2, n - 1 - i, popcount + 1)) % (popcount + 1);
      if (nmod < 0)
        nmod += popcount + 1;
    }
    cout << calcf(nmod) + 1 << endl;
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#include <iostream>
using namespace std;

int startx[200000];

int modpow(int a, int b, int m) {
  int prebit = a % m;
  int ans = 1;
  for (int bit = 0; (long unsigned int)b >= (1UL << bit); bit++) {
    if (bit > 0)
      prebit = (prebit * prebit) % m;
    if (b & (1UL << bit))
      ans = (ans * prebit) % m;
  }
  return ans;
}

// x <= n
int calcf(int x) {
  if (x == 0)
    return 0;
  int popcount = 0;
  for (int i = 0; (1 << i) <= x; i++) {
    if ((1 << i) & x)
      popcount++;
  }
  return calcf(x % popcount) + 1;
}

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

  int popcount = 0;
  for (int i = 0; i < n; i++) {
    startx[i] = (s[i] == '1' ? 1 : 0);
    if (startx[i] == 1)
      popcount++;
  }
  int mod0 = 0;
  if (popcount > 1) {
    // popcount - 1でxをわったときのあまりを求める
    for (int i = 0; i < n; i++) {
      mod0 = (mod0 * 2) % (popcount - 1);
      if (startx[i] == 1)
        mod0 = (mod0 + 1) % (popcount - 1);
    }
  }
  int mod1 = 0;
  for (int i = 0; i < n; i++) {
    mod1 = (mod1 * 2) % (popcount + 1);
    if (startx[i] == 1)
      mod1 = (mod1 + 1) % (popcount + 1);
  }

  for (int i = 0; i < n; i++) {
    int nmod = 0;
    if (startx[i] == 1) {
      // 1 -> 0
      if (popcount - 1 > 0) {
        nmod = (mod0 - modpow(2, n - 1 - i, popcount - 1)) % (popcount - 1);
        if (nmod < 0)
          nmod += popcount - 1;
      } else {
        cout << 0 << endl;
        continue;
      }
    } else {
      nmod = (mod1 + modpow(2, n - 1 - i, popcount + 1)) % (popcount + 1);
      if (nmod < 0)
        nmod += popcount + 1;
    }
    cout << calcf(nmod) + 1 << endl;
  }
}