Problem p02609 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

long long MOD = 1000000000 + 7;

ll pow2mod(ll x, ll y) {
  // 2^x を yで割ったあまり
  ll ret = 0;

  if (y == 0)
    return 0;
  if (y == 1)
    return 0;
  if (x == 0)
    return 1;
  if (x == 1)
    return 2 % y;

  if (x % 2 == 0) {
    ret = pow2mod(x / 2, y);
    return (ret * ret) % y;
  }
  if (x % 2 == 1) {
    ret = pow2mod(x - 1, y) * 2;
    return ret % y;
  }
  return 0;
}

map<ll, int> m;

int solve(int x, int num) {
  if (x == 0)
    return num;
  if (x == 1)
    return (num + 1);
  ll p = __builtin_popcount(x);

  if (p == 0) {
    return num;
  }

  if (x % p == 0) {
    return (num + 1);
  } else {
    return solve(x % p, num + 1);
  }
}

int main() {
  cout << setprecision(10);

  int N;
  cin >> N;
  string X;
  cin >> X;

  ll y = 0;
  for (char c : X) {
    if (c == '1')
      y++;
  }

  // X % (y+1)と、X%(y-1)を調べておく

  int modyp1 = 0;
  int modym1 = 0;
  for (int i = 0; i < N; i++) {
    if (X[i] == '0')
      continue;

    modyp1 += pow2mod(N - i - 1, y + 1);
    modyp1 %= (y + 1);
    modym1 += pow2mod(N - i - 1, y - 1);
    modym1 %= (y - 1);
  }

  cerr << modyp1 << " " << modym1 << endl;

  for (int i = 0; i < N; i++) {
    int j = N - i - 1;
    if (X[i] == '0') {
      int tmp = modyp1;         // X%(y+1)
      tmp += pow2mod(j, y + 1); // y+1でわったあまりが得られた
      tmp %= (y + 1);
      // cerr << "i: " << i << " tmp: " << tmp  << " y+1: " << y+1 << endl;
      cout << solve(tmp, 1) << endl;
    } else {
      int tmp = modym1;         // X%(y-1)
      tmp -= pow2mod(j, y - 1); // y-1でわったあまりが得られた
      tmp += y - 1;
      if (y - 1 == 0) {
        cout << 0 << endl;
      } else {
        tmp %= (y - 1);
        // cerr << "i: " << i << " tmp: " << tmp  << " y-1: " << y-1 << endl;
        cout << solve(tmp, 1) << endl;
      }
    }
  }
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

long long MOD = 1000000000 + 7;

ll pow2mod(ll x, ll y) {
  // 2^x を yで割ったあまり
  ll ret = 0;

  if (y == 0)
    return 0;
  if (y == 1)
    return 0;
  if (x == 0)
    return 1;
  if (x == 1)
    return 2 % y;

  if (x % 2 == 0) {
    ret = pow2mod(x / 2, y);
    return (ret * ret) % y;
  }
  if (x % 2 == 1) {
    ret = pow2mod(x - 1, y) * 2;
    return ret % y;
  }
  return 0;
}

map<ll, int> m;

int solve(int x, int num) {
  if (x == 0)
    return num;
  if (x == 1)
    return (num + 1);
  ll p = __builtin_popcount(x);

  if (p == 0) {
    return num;
  }

  if (x % p == 0) {
    return (num + 1);
  } else {
    return solve(x % p, num + 1);
  }
}

int main() {
  cout << setprecision(10);

  int N;
  cin >> N;
  string X;
  cin >> X;

  ll y = 0;
  for (char c : X) {
    if (c == '1')
      y++;
  }

  // X % (y+1)と、X%(y-1)を調べておく

  int modyp1 = 0;
  int modym1 = 0;
  for (int i = 0; i < N; i++) {
    if (X[i] == '0')
      continue;

    modyp1 += pow2mod(N - i - 1, y + 1);
    modyp1 %= (y + 1);
    modym1 += pow2mod(N - i - 1, y - 1);
    if (y - 1 == 0) {
      modym1 = 0;
    } else {
      modym1 %= y - 1;
    }
  }

  cerr << modyp1 << " " << modym1 << endl;

  for (int i = 0; i < N; i++) {
    int j = N - i - 1;
    if (X[i] == '0') {
      int tmp = modyp1;         // X%(y+1)
      tmp += pow2mod(j, y + 1); // y+1でわったあまりが得られた
      tmp %= (y + 1);
      // cerr << "i: " << i << " tmp: " << tmp  << " y+1: " << y+1 << endl;
      cout << solve(tmp, 1) << endl;
    } else {
      int tmp = modym1;         // X%(y-1)
      tmp -= pow2mod(j, y - 1); // y-1でわったあまりが得られた
      tmp += y - 1;
      if (y - 1 == 0) {
        cout << 0 << endl;
      } else {
        tmp %= (y - 1);
        // cerr << "i: " << i << " tmp: " << tmp  << " y-1: " << y-1 << endl;
        cout << solve(tmp, 1) << endl;
      }
    }
  }
}