Problem p02609 (C++)

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

long long M;

long long BigMod(long long b, long long m) {
  long long a = 2;
  a %= m;
  long long res = 1;
  while (b > 0) {
    if (b & 1)
      res = (res * a) % m;
    a = (a * a) % m;
    b >>= 1;
  }
  return res;
}

long long f(long long n) {
  long long step = 0;
  while (__builtin_popcount(n)) {
    step++;
    int x = __builtin_popcount(n);
    n %= x;
  }
  return step;
}

int main() {
  int n;
  scanf("%d", &n);
  string x;
  cin >> x;
  long long num_of_one = 0;
  for (int i = 0; i < x.size(); i++) {
    num_of_one += x[i] == '1';
  }
  reverse(x.begin(), x.end());

  long long mod_zero[300000];
  long long mod_one[300000];
  memset(mod_zero, 0, sizeof(mod_zero));
  memset(mod_one, 0, sizeof(mod_one));
  for (int i = 0; i < n; i++) {
    if (x[i] == '1') {
      mod_zero[i] = BigMod(i, num_of_one + 1);
      mod_one[i] = BigMod(i, num_of_one - 1);
    }
    if (i > 0) {
      mod_zero[i] += mod_zero[i - 1];
      mod_zero[i] %= (num_of_one + 1);
      mod_one[i] += mod_one[i - 1];
      if (num_of_one > 1) {
        mod_one[i] %= (num_of_one - 1);
      }
    }
  }
  long long m_1 = mod_zero[n - 1];
  long long m_2 = mod_one[n - 1];

  long long les = num_of_one - 1;
  long long gre = num_of_one + 1;

  long long ans[300000];
  for (int i = 0; i < n; i++) {
    if (x[i] == '1') {
      if (les > 0) {
        long long k = BigMod(i, les);
        long long z = (m_2 - k) % les;
        if (z < 0)
          z += les;
        ans[i] = 1 + f(z);
      } else {
        ans[i] = 0;
      }

    } else {
      long long k = BigMod(i, gre);
      long long z = (m_1 + k) % gre;
      ans[i] = 1 + f(z);
    }
  }
  for (int i = n - 1; i >= 0; i--) {
    printf("%lld\n", ans[i]);
  }
}


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

long long M;

long long BigMod(long long b, long long m) {
  if (m == 0)
    return 0;
  long long a = 2;
  a %= m;
  long long res = 1;
  while (b > 0) {
    if (b & 1)
      res = (res * a) % m;
    a = (a * a) % m;
    b >>= 1;
  }
  return res;
}

long long f(long long n) {
  long long step = 0;
  while (__builtin_popcount(n)) {
    step++;
    int x = __builtin_popcount(n);
    n %= x;
  }
  return step;
}

int main() {
  int n;
  scanf("%d", &n);
  string x;
  cin >> x;
  long long num_of_one = 0;
  for (int i = 0; i < x.size(); i++) {
    num_of_one += x[i] == '1';
  }
  reverse(x.begin(), x.end());

  long long mod_zero[300000];
  long long mod_one[300000];
  memset(mod_zero, 0, sizeof(mod_zero));
  memset(mod_one, 0, sizeof(mod_one));
  for (int i = 0; i < n; i++) {
    if (x[i] == '1') {
      mod_zero[i] = BigMod(i, num_of_one + 1);
      mod_one[i] = BigMod(i, num_of_one - 1);
    }
    if (i > 0) {
      mod_zero[i] += mod_zero[i - 1];
      mod_zero[i] %= (num_of_one + 1);
      mod_one[i] += mod_one[i - 1];
      if (num_of_one > 1) {
        mod_one[i] %= (num_of_one - 1);
      }
    }
  }
  long long m_1 = mod_zero[n - 1];
  long long m_2 = mod_one[n - 1];

  long long les = num_of_one - 1;
  long long gre = num_of_one + 1;

  long long ans[300000];
  for (int i = 0; i < n; i++) {
    if (x[i] == '1') {
      if (les > 0) {
        long long k = BigMod(i, les);
        long long z = (m_2 - k) % les;
        if (z < 0)
          z += les;
        ans[i] = 1 + f(z);
      } else {
        ans[i] = 0;
      }

    } else {
      long long k = BigMod(i, gre);
      long long z = (m_1 + k) % gre;
      ans[i] = 1 + f(z);
    }
  }
  for (int i = n - 1; i >= 0; i--) {
    printf("%lld\n", ans[i]);
  }
}