Problem p02609 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

#include <limits.h>

using namespace std;

typedef long long ll;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

const int MAX_N = 200000 * 2;

map<ll, vector<ll>> powers;

ll f(ll mod, int bit, bool to_one, const string &original_S) {
  // printf("mod: %lld, bit: %d, to_one: %d, %s\n", mod, bit, to_one,
  // original_S.c_str());
  static map<ll, ll> memo;
  if (powers.find(mod) == powers.end()) {
    // power[i] is 2 ^ i % mod
    vector<ll> power(MAX_N + 10);
    power[0] = 1 % mod;

    for (int i = 1; i <= MAX_N; i++) {
      power[i] = (power[i - 1] * 2) % mod;
      // printf("power[%d]: %lld\n", i, power[i]);
    }
    powers[mod] = power;
  }

  vector<ll> &power = powers[mod];

  if (memo.find(mod) == memo.end()) {
    ll v = 0;
    string T = original_S;
    reverse(T.begin(), T.end());
    for (int i = 0; i < (int)T.size(); i++) {
      if (T[i] == '1') {
        v = (v + power[i]) % mod;
      }
    }
    memo[mod] = v;
  }

  ll ans = memo[mod];
  // printf("memo: %lld\n", ans);

  if (to_one) {
    ans = (ans + power[bit]) % mod;
  } else {
    // if ((x += MOD-a.x) >= MOD) x -= MOD;
    if ((ans += mod - power[bit]) >= mod)
      ans -= mod;
    // ans = (ans - power[bit]) % mod;
    // while (ans < 0) {
    //     ans += mod;
    // }
  }

  // string T = S;
  // reverse(T.begin(), T.end());
  // for (int i = 0; i < (int) T.size(); i++) {
  //     if (T[i] == '1') {
  //         ans = (ans + (*power)[i]) % mod;
  //     }
  // }

  return ans;
}

int count_bit(const string &S) {
  int ans = 0;

  for (int i = 0; i < (int)S.size(); i++) {
    if (S[i] == '1') {
      ans++;
    }
  }

  return ans;
}

int main(void) {
  int N;
  cin >> N;
  string S;
  cin >> S;

  const int bit_count = count_bit(S);
  // printf("bit_count: %d\n", bit_count);

  for (int i = 0; i < N; i++) {
    string T = S;
    ll mod;
    if (T[i] == '1') {
      T[i] = '0';
      mod = bit_count - 1;
    } else {
      T[i] = '1';
      mod = bit_count + 1;
    }
    // printf("%s, %lld\n", T.c_str(), mod);
    // printf("%d: %lld\n", i, f(mod, T));

    ll x = f(mod, N - i - 1, T[i] == '1', S);

    int cnt = 1;
    // printf("x: %lld\n", x);
    while (x > 0) {
      int bit_count = __builtin_popcountll(x);
      // printf("x: %lld, bit_count: %d\n", x, bit_count);
      x = x % bit_count; // f(bit_count, to_string(x));
      cnt++;
    }

    printf("%d\n", cnt);
  }

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

#include <limits.h>

using namespace std;

typedef long long ll;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

const int MAX_N = 200000 * 2;

map<ll, vector<ll>> powers;

ll f(ll mod, int bit, bool to_one, const string &original_S) {
  // printf("mod: %lld, bit: %d, to_one: %d, %s\n", mod, bit, to_one,
  // original_S.c_str());
  static map<ll, ll> memo;
  if (powers.find(mod) == powers.end()) {
    // power[i] is 2 ^ i % mod
    vector<ll> power(MAX_N + 10);
    power[0] = 1 % mod;

    for (int i = 1; i <= MAX_N; i++) {
      power[i] = (power[i - 1] * 2) % mod;
      // printf("power[%d]: %lld\n", i, power[i]);
    }
    powers[mod] = power;
  }

  vector<ll> &power = powers[mod];

  if (memo.find(mod) == memo.end()) {
    ll v = 0;
    string T = original_S;
    reverse(T.begin(), T.end());
    for (int i = 0; i < (int)T.size(); i++) {
      if (T[i] == '1') {
        v = (v + power[i]) % mod;
      }
    }
    memo[mod] = v;
  }

  ll ans = memo[mod];
  // printf("memo: %lld\n", ans);

  if (to_one) {
    ans = (ans + power[bit]) % mod;
  } else {
    // if ((x += MOD-a.x) >= MOD) x -= MOD;
    if ((ans += mod - power[bit]) >= mod)
      ans -= mod;
    // ans = (ans - power[bit]) % mod;
    // while (ans < 0) {
    //     ans += mod;
    // }
  }

  // string T = S;
  // reverse(T.begin(), T.end());
  // for (int i = 0; i < (int) T.size(); i++) {
  //     if (T[i] == '1') {
  //         ans = (ans + (*power)[i]) % mod;
  //     }
  // }

  return ans;
}

int count_bit(const string &S) {
  int ans = 0;

  for (int i = 0; i < (int)S.size(); i++) {
    if (S[i] == '1') {
      ans++;
    }
  }

  return ans;
}

int main(void) {
  int N;
  cin >> N;
  string S;
  cin >> S;

  const int bit_count = count_bit(S);
  // printf("bit_count: %d\n", bit_count);

  for (int i = 0; i < N; i++) {
    string T = S;
    ll mod;
    if (T[i] == '1') {
      T[i] = '0';
      mod = bit_count - 1;
    } else {
      T[i] = '1';
      mod = bit_count + 1;
    }
    // printf("%s, %lld\n", T.c_str(), mod);
    // printf("%d: %lld\n", i, f(mod, T));

    if (mod == 0) {
      printf("%d\n", 0);
      continue;
    }
    ll x = f(mod, N - i - 1, T[i] == '1', S);

    int cnt = 1;
    // printf("x: %lld\n", x);
    while (x > 0) {
      int bit_count = __builtin_popcountll(x);
      // printf("x: %lld, bit_count: %d\n", x, bit_count);
      x = x % bit_count; // f(bit_count, to_string(x));
      cnt++;
    }

    printf("%d\n", cnt);
  }

  return 0;
}