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

#include <algorithm>
#include <deque>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unordered_map>
#include <vector>

long long mod = 1e9 + 7;
class Mint {
public:
  long long x;
  Mint(){}; // 引数なしでも定義できるように引数なしコンストラクタも用意しておく
  Mint(long long a) {
    x = a % mod;
    while (x < 0) {
      x += mod;
    }
  };
  Mint &operator+=(const Mint &a) {
    x += a.x;
    x %= mod;
    return *this;
  }
  Mint &operator-=(const Mint &a) {
    x += (mod - a.x);
    x %= mod;
    return *this;
  }
  Mint &operator*=(const Mint &a) {
    x *= a.x;
    x %= mod;
    return *this;
  }

  // a^n mod を計算する
  // Useaeg: Mint z = y.pow(y, n);
  Mint pow(Mint a, long long n) const {
    Mint y(1);
    Mint b(a);
    while (n > 0) {
      if (n & 1)
        y *= b;
      b *= b;
      n >>= 1;
    }
    return y;
  }

  // a^{-1} mod を計算する
  Mint modinv(const Mint &a) const { return pow(a, mod - 2); }

  Mint &operator/=(const Mint &a) {
    x *= modinv(a).x;
    x %= mod;
    return *this;
  }

  Mint operator+(Mint &a) const {
    Mint y(*this);
    y += a;
    return y;
  }

  Mint operator-(Mint &a) const {
    Mint y(*this);
    y -= a;
    return y;
  }

  Mint operator*(Mint &a) const {
    Mint y(*this);
    y *= a;
    return y;
  }

  Mint operator/(Mint &a) const {
    Mint y(*this);
    y /= a;
    return y.x;
  }

  // nCk @mod を計算する
  Mint nCk(Mint &n, const long long k) const {
    Mint y = Mint(1);
    for (Mint i(0); (i.x) < k; i.x++) {
      y *= (n - i);
      y /= i;
    }
    return y;
  }

  // nPk @mod を計算する
  Mint nPk(Mint &n, long long k) const {
    Mint y(1);
    for (Mint i(0); (i.x) < k; i.x++) {
      y *= (n - i);
    }
    return y;
  }
};

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

  int cnt = 0;
  for (int i = 0; i < n; i++) {
    if (s[i] == '1')
      cnt++;
  }

  if (cnt == 0) {
    for (int i = 0; i < n; i++) {
      printf("1\\n");
    }
    return 0;
  }
  // n=200000;
  // printf("kuso\\n");
  /*for (int i=0; i<200000; i++){
    //printf("i-%d\\n", i);
    s+='1';
  }*/
  // printf("hi\\n");
  std::vector<long long> f(200004, 0);
  f[0] = 0;
  f[1] = 1;
  for (int i = 2; i < 200004; i++) {
    int nn = i;
    int cnt = 0;
    while (nn > 0) {
      if (nn % 2 == 1)
        cnt++;
      nn = nn / 2;
    }
    // printf("i=%d\\n", i);
    f[i] = 1 + f[i % cnt];
  }
  // printf("hoge\\n");
  Mint ni(2);

  // printf("cnt=%d\\n", cnt);

  Mint multiple(1);

  // minus
  long long amari_minus = 0;
  multiple = 1;
  mod = (long long)cnt - 1;
  int mul = 1;
  if (cnt > 1) {
    mul = 1;
    for (int i = n - 1; i >= 0; i--) {
      if (s[i] == '1') {
        amari_minus += mul;
        amari_minus %= (cnt - 1);
      }
      mul *= 2;
      mul %= (cnt - 1);
    }
  }

  // plus
  long long amari_plus = 0;
  multiple = 1;
  mod = (long long)cnt + 1;
  int sum = 0;
  mul = 1;
  for (int i = n - 1; i >= 0; i--) {
    if (s[i] == '1') {
      amari_plus += mul;
      amari_plus %= (cnt + 1);
      sum += mul;
    }
    multiple *= ni;
    mul *= 2;
    mul %= (cnt + 1);
  }
  // printf("amari_plus=%lld\\n", amari_plus);
  // printf("amari_minus=%lld\\n", amari_minus);
  // printf("sum=%d\\n", sum);

  std::vector<long long> ans(n + 4, 0);
  mod = (long long)cnt + 1;
  mul = 1;
  for (int i = n - 1; i >= 0; i--) {
    long long orig = amari_plus;
    if (s[i] == '1') {
    } else {
      orig += mul;
      orig %= (cnt + 1);
      ans[i] = 1 + f[orig];
      // printf("plus, ans[%d]=1+f[%lld]=%lld\\n", i, amari_plus, ans[i]);
    }
    mul *= 2;
    mul %= (cnt + 1);
  }

  if (cnt > 1) {
    // mod = (long long )cnt-1;
    mul = 1;
    for (int i = n - 1; i >= 0; i--) {
      long long orig = amari_minus;
      if (s[i] == '0') {
      } else {
        orig -= (long long)mul;
        while (orig < 0) {
          orig += (long long)(cnt - 1);
        }
        // if (i==19) printf("i=%d, amari_minus=%lld\\n", i, orig);
        // if (i<0 || i>n+3 || orig<0 || orig>200004) while(true){}
        // f[orig]=3;
        ans[i] = 1 + f[orig];
        // ans[i]=3;
        // printf("minus, ans[%d]=1+f[%lld]=%lld\\n", i, amari_minus, ans[i]);
      }
      mul *= 2;
      mul %= (cnt - 1);
    }
  }
  // std::reverse(ans.begin(), ans.end());
  for (int i = 0; i < n; i++) {
    printf("%lld\\n", ans[i]);
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <deque>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unordered_map>
#include <vector>

long long mod = 1e9 + 7;
class Mint {
public:
  long long x;
  Mint(){}; // 引数なしでも定義できるように引数なしコンストラクタも用意しておく
  Mint(long long a) {
    x = a % mod;
    while (x < 0) {
      x += mod;
    }
  };
  Mint &operator+=(const Mint &a) {
    x += a.x;
    x %= mod;
    return *this;
  }
  Mint &operator-=(const Mint &a) {
    x += (mod - a.x);
    x %= mod;
    return *this;
  }
  Mint &operator*=(const Mint &a) {
    x *= a.x;
    x %= mod;
    return *this;
  }

  // a^n mod を計算する
  // Useaeg: Mint z = y.pow(y, n);
  Mint pow(Mint a, long long n) const {
    Mint y(1);
    Mint b(a);
    while (n > 0) {
      if (n & 1)
        y *= b;
      b *= b;
      n >>= 1;
    }
    return y;
  }

  // a^{-1} mod を計算する
  Mint modinv(const Mint &a) const { return pow(a, mod - 2); }

  Mint &operator/=(const Mint &a) {
    x *= modinv(a).x;
    x %= mod;
    return *this;
  }

  Mint operator+(Mint &a) const {
    Mint y(*this);
    y += a;
    return y;
  }

  Mint operator-(Mint &a) const {
    Mint y(*this);
    y -= a;
    return y;
  }

  Mint operator*(Mint &a) const {
    Mint y(*this);
    y *= a;
    return y;
  }

  Mint operator/(Mint &a) const {
    Mint y(*this);
    y /= a;
    return y.x;
  }

  // nCk @mod を計算する
  Mint nCk(Mint &n, const long long k) const {
    Mint y = Mint(1);
    for (Mint i(0); (i.x) < k; i.x++) {
      y *= (n - i);
      y /= i;
    }
    return y;
  }

  // nPk @mod を計算する
  Mint nPk(Mint &n, long long k) const {
    Mint y(1);
    for (Mint i(0); (i.x) < k; i.x++) {
      y *= (n - i);
    }
    return y;
  }
};

int main() {
  int n;
  std::cin >> n;
  std::string s;
  std::cin >> s;
  // n=200000;
  // printf("kuso\\n");
  /*for (int i=0; i<200000; i++){
    //printf("i-%d\\n", i);
    s+='1';
  }*/
  // printf("hi\\n");
  std::vector<long long> f(200004, 0);
  f[0] = 0;
  f[1] = 1;
  for (int i = 2; i < 200004; i++) {
    int nn = i;
    int cnt = 0;
    while (nn > 0) {
      if (nn % 2 == 1)
        cnt++;
      nn = nn / 2;
    }
    // printf("i=%d\\n", i);
    f[i] = 1 + f[i % cnt];
  }
  // printf("hoge\\n");
  Mint ni(2);
  int cnt = 0;
  for (int i = 0; i < n; i++) {
    if (s[i] == '1')
      cnt++;
  }
  // printf("cnt=%d\\n", cnt);

  Mint multiple(1);
  /*// base
  Mint amari_base(1);

  mod = (long long)cnt;
  for (int i=n-1; i>=0; i--){
    if (s[i]=='1') {
      amari_base += multiple;
    }
    multiple *= ni;
  }*/

  // minus
  long long amari_minus = 0;
  multiple = 1;
  mod = (long long)cnt - 1;
  int mul = 1;
  if (cnt > 0) {
    mul = 1;
    for (int i = n - 1; i >= 0; i--) {
      if (s[i] == '1') {
        amari_minus += mul;
        amari_minus %= (cnt - 1);
      }
      mul *= 2;
      mul %= (cnt - 1);
    }
  }

  // plus
  long long amari_plus = 0;
  multiple = 1;
  mod = (long long)cnt + 1;
  int sum = 0;
  mul = 1;
  for (int i = n - 1; i >= 0; i--) {
    if (s[i] == '1') {
      amari_plus += mul;
      amari_plus %= (cnt + 1);
      sum += mul;
    }
    multiple *= ni;
    mul *= 2;
    mul %= (cnt + 1);
  }
  // printf("amari_plus=%lld\\n", amari_plus);
  // printf("amari_minus=%lld\\n", amari_minus);
  // printf("sum=%d\\n", sum);

  std::vector<long long> ans(n + 4, 0);
  mod = (long long)cnt + 1;
  mul = 1;
  for (int i = n - 1; i >= 0; i--) {
    long long orig = amari_plus;
    if (s[i] == '1') {
    } else {
      orig += mul;
      orig %= (cnt + 1);
      ans[i] = 1 + f[orig];
      // printf("plus, ans[%d]=1+f[%lld]=%lld\\n", i, amari_plus, ans[i]);
    }
    mul *= 2;
    mul %= (cnt + 1);
  }

  if (cnt > 0) {
    // mod = (long long )cnt-1;
    mul = 1;
    for (int i = n - 1; i >= 0; i--) {
      long long orig = amari_minus;
      if (s[i] == '0') {
      } else {
        if (cnt == 1) {
          ans[i] = 0;
          break;
        }
        // if (i==19) printf("i=%d, amari_minus_orig=%lld\\n", i, amari_minus);
        orig -= (long long)mul;
        while (orig < 0) {
          orig += (long long)(cnt - 1);
        }
        // if (i==19) printf("i=%d, amari_minus=%lld\\n", i, orig);
        // if (i<0 || i>n+3 || orig<0 || orig>200004) while(true){}
        // f[orig]=3;
        ans[i] = 1 + f[orig];
        // ans[i]=3;
        // printf("minus, ans[%d]=1+f[%lld]=%lld\\n", i, amari_minus, ans[i]);
      }
      mul *= 2;
      if (cnt - 1 > 0)
        mul %= (cnt - 1);
    }
  }
  // std::reverse(ans.begin(), ans.end());
  for (int i = 0; i < n; i++) {
    printf("%lld\\n", ans[i]);
  }
  return 0;
}