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

#include <bits/stdc++.h>
#define INF 1e9
using namespace std;

#define REPR(i, n) for (int i = (n); i >= 0; --i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define ALL(a) (a).begin(), (a).end()
#define endl "\\n"

template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
typedef long long ll;

map<int, int> mp; // 一回実行した結果を格納

int rec(map<int, int> &m, int val) {
  int pc = __builtin_popcount(val);
  if ((val % pc) == 0) {
    return 1;
  }
  m[val] = rec(m, val % pc) + 1;
  return m[val];
}

void solve() {
  mp = map<int, int>();
  int maxi = 2 * 1e5 + 10;
  int N;
  string X;
  cin >> N;
  cin >> X;
  int rawcount = 0;
  for (const auto &c : X)
    if (c == '1')
      rawcount++;

  // mods[i] = 2^(i) mod n
  // nは2種類しかない→popcountはx+1,x-1
  vector<int> minus_mods(maxi, 0);
  vector<int> plus_mods(maxi, 0);
  minus_mods[0] = 1;
  plus_mods[0] = 1;

  // 1 -> 0
  int minus_pc = max(1, rawcount - 1);
  bool care = (rawcount - 1) == 0;
  // 0 -> 1
  int plus_pc = rawcount + 1;

  FOR(i, 1, maxi) {
    minus_mods[i] = (minus_mods[i - 1] * 2) % minus_pc;
    plus_mods[i] = (plus_mods[i - 1] * 2) % plus_pc;
  }

  int sm_minus_mods = 0;
  int sm_plus_mods = 0;

  REP(i, X.size()) {
    int ketame = X.size() - i - 1;
    if (X[i] - '0')
      sm_minus_mods += minus_mods[ketame];
    if (X[i] - '0')
      sm_plus_mods += plus_mods[ketame];
    sm_minus_mods %= minus_pc;
    sm_plus_mods %= plus_pc;
  }

  vector<int> v(X.size());
  mp[1] = 1;
  mp[0] = 0;
  REP(i, X.size()) {
    int ketame = X.size() - i - 1;
    // どっちのポップカウントを使うか
    if (X[i] - '0') {
      if (care) {
        v[i] = -1;
        continue;
      }
      int csmm = sm_minus_mods;
      // 1 -> 0
      csmm -= minus_mods[ketame];
      if (csmm < 0)
        csmm += minus_pc;
      v[i] = csmm;
    } else {
      int cspm = sm_plus_mods;
      // 0 -> 1
      cspm += plus_mods[ketame];
      cspm %= plus_pc;
      v[i] = cspm;
    }
  }

  // 一回やればmaxi以下になるので一回だけやる　
  for (const auto &it : v) {
    // 取り出す
    int state = it;
    bool end = false;
    if (state == 0) {
      cout << 1 << endl;
      continue;
    }
    if (state < 0) {
      cout << 0 << endl;
      continue;
    }
    while (!end) {
      int pc = __builtin_popcount(state);
      if (mp.count(state % pc)) {
        mp[state] = mp[state % pc] + 1;
        end = true;
        break;
      } else {
        rec(mp, state);
        end = true;
      }
    }
    cout << mp[state] + 1 << endl;
  }
}

int main() {
  solve();
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define INF 1e9
using namespace std;

#define REPR(i, n) for (int i = (n); i >= 0; --i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define ALL(a) (a).begin(), (a).end()
#define endl "\\n"

template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
typedef long long ll;

map<int, int> mp; // 一回実行した結果を格納

int rec(map<int, int> &m, int val) {
  int pc = __builtin_popcount(val);
  if ((val % pc) == 0) {
    return 1;
  }
  m[val] = rec(m, val % pc) + 1;
  return m[val];
}

void solve() {
  mp = map<int, int>();
  int maxi = 2 * 1e5 + 1;
  int N;
  string X;
  cin >> N;
  cin >> X;
  int rawcount = 0;
  for (const auto &c : X)
    if (c == '1')
      rawcount++;

  // mods[i] = 2^(i) mod n
  // nは2種類しかない→popcountはx+1,x-1
  vector<int> minus_mods(maxi, 0);
  vector<int> plus_mods(maxi, 0);
  minus_mods[0] = 1;
  plus_mods[0] = 1;

  // 1 -> 0
  int minus_pc = rawcount - 1;

  // 0 -> 1
  int plus_pc = rawcount + 1;

  FOR(i, 1, maxi) {
    minus_mods[i] = (minus_mods[i - 1] << 1) % minus_pc;
    plus_mods[i] = (plus_mods[i - 1] << 1) % plus_pc;
  }

  int sm_minus_mods = 0;
  int sm_plus_mods = 0;

  REP(i, X.size()) {
    int ketame = X.size() - i - 1;
    if (X[i] - '0')
      sm_minus_mods += minus_mods[ketame];
    if (X[i] - '0')
      sm_plus_mods += plus_mods[ketame];
    sm_minus_mods %= minus_pc;
    sm_plus_mods %= plus_pc;
  }

  vector<int> v(X.size());
  mp[1] = 1;
  mp[0] = 0;
  REP(i, X.size()) {
    int ketame = X.size() - i - 1;
    // どっちのポップカウントを使うか
    if (X[i] - '0') {
      int csmm = sm_minus_mods;
      // 1 -> 0
      csmm -= minus_mods[ketame];
      if (csmm < 0)
        csmm += minus_pc;
      v[i] = csmm;
    } else {
      int cspm = sm_plus_mods;
      // 0 -> 1
      cspm += plus_mods[ketame];
      cspm %= plus_pc;
      v[i] = cspm;
    }
  }

  // 一回やればmaxi以下になるので一回だけやる　
  for (const auto &it : v) {
    // 取り出す
    int state = it;
    int cnt = 0;
    bool end = false;
    if (state == 0) {
      cout << 1 << endl;
      continue;
    }
    while (!end) {
      int pc = __builtin_popcount(state);
      if (mp.count(state % pc)) {
        mp[state] = mp[state % pc] + 1;
        end = true;
        break;
      } else {
        rec(mp, state);
        end = true;
      }
    }
    cout << mp[state] + 1 << endl;
  }
}

int main() {
  solve();
  return 0;
}