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

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

long long N;
string Xstr;

long long ups[200005];
long long downs[200005];

long long modpow(long long ori, long long po, long long div) {
  long long res = 1;
  while (po > 0) {
    if (po & 1) {
      res *= ori;
      res %= div;
    }
    ori *= ori;
    ori %= div;
    po >>= 1;
  }
  return res;
}

long long countbit(long long n) {
  long long ans = 0;
  while (n) {
    if ((n & 1) == 1) {
      ans++;
    }
    n >>= 1;
  }
  return ans;
}

long long cal(long long n) {
  if (n == 0) {
    return 0;
  }
  long long ans = cal(n % countbit(n));

  return ans + 1;
}

int main() {
  cin >> N;
  cin >> Xstr;
  long long onecount = 0;
  for (long long i = 0; i < Xstr.length(); i++) {
    if (Xstr[i] == '1') {
      onecount++;
    }
  }

  long long onecountup = onecount + 1;
  long long onecountdown = onecount - 1;

  // cout << "onecountup = " << onecountup << endl;
  // cout << "onecountdown = " << onecountdown << endl;

  long long uppop = 0;
  long long downpop = 0;

  // up
  if (onecountup > 0) {
    for (long long i = 0; i < N; i++) {
      long long po = N - i - 1;
      ups[i] = modpow(2, po, onecountup);
      if (Xstr[i] == '1') {
        uppop += ups[i];
        uppop %= onecountup;
      }
    }
  }

  // down
  if (onecountdown > 0) {
    for (long long i = 0; i < N; i++) {
      long long po = N - i - 1;
      downs[i] = modpow(2, po, onecountdown);
      if (Xstr[i] == '1') {
        downpop += downs[i];
        downpop %= onecountdown;
      }
    }
  }

  // for(long long i = 0; i < N; i++) {
  //	cout << "ups[" << i << "] = " << ups[i] << endl;
  // }
  // cout << "uppop = " << uppop << endl;

  // for(long long i = 0; i < N; i++) {
  //	cout << "downs[" << i << "] = " << downs[i] << endl;
  // }
  // cout << "downpop = " << downpop << endl;

  for (long long i = 0; i < N; i++) {
    if (Xstr[i] == '1') {
      if (onecountdown == 0) {
        cout << 0 << endl;
      } else {
        // down
        long long tmp = (downpop - downs[i] + onecountdown) % onecountdown;
        // cout << "tmp = " << tmp << endl;
        cout << cal(tmp) + 1 << endl;
      }
    } else {
      if (onecountup == 0) {
        cout << 1 << endl;
      } else {
        // up
        long long tmp = (uppop + ups[i] + onecountup) % onecountup;
        // cout << "tmp = " << tmp << endl;
        cout << cal(tmp) + 1 << endl;
      }
    }
  }
}

Error: 0

Fixed submission:

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

long long N;
string Xstr;

long long ups[200005];
long long downs[200005];

long long modpow(long long ori, long long po, long long div) {
  long long res = 1;
  while (po > 0) {
    if (po & 1) {
      res *= ori;
      res %= div;
    }
    ori *= ori;
    ori %= div;
    po >>= 1;
  }
  return res;
}

long long countbit(long long n) {
  long long ans = 0;
  while (n) {
    if ((n & 1) == 1) {
      ans++;
    }
    n >>= 1;
  }
  return ans;
}

long long cal(long long n) {
  if (n == 0) {
    return 0;
  }
  long long ans = cal(n % countbit(n));

  return ans + 1;
}

int main() {
  cin >> N;
  cin >> Xstr;
  long long onecount = 0;
  for (long long i = 0; i < Xstr.length(); i++) {
    if (Xstr[i] == '1') {
      onecount++;
    }
  }

  long long onecountup = onecount + 1;
  long long onecountdown = onecount - 1;

  // cout << "onecountup = " << onecountup << endl;
  // cout << "onecountdown = " << onecountdown << endl;

  long long uppop = 0;
  long long downpop = 0;

  // up
  for (long long i = 0; i < N; i++) {
    long long po = N - i - 1;
    ups[i] = modpow(2, po, onecountup);
    if (Xstr[i] == '1') {
      uppop += ups[i];
      uppop %= onecountup;
    }
  }

  // down
  for (long long i = 0; i < N; i++) {
    long long po = N - i - 1;
    downs[i] = modpow(2, po, onecountdown);
    if (Xstr[i] == '1') {
      downpop += downs[i];
      downpop %= onecountdown;
    }
  }

  // for(long long i = 0; i < N; i++) {
  //	cout << "ups[" << i << "] = " << ups[i] << endl;
  // }
  // cout << "uppop = " << uppop << endl;

  // for(long long i = 0; i < N; i++) {
  //	cout << "downs[" << i << "] = " << downs[i] << endl;
  // }
  // cout << "downpop = " << downpop << endl;

  for (long long i = 0; i < N; i++) {
    if (Xstr[i] == '1') {
      // down
      long long tmp = (downpop - downs[i] + onecountdown) % onecountdown;
      // cout << "tmp = " << tmp << endl;
      cout << cal(tmp) + 1 << endl;
    } else {
      // up
      long long tmp = (uppop + ups[i] + onecountup) % onecountup;
      // cout << "tmp = " << tmp << endl;
      cout << cal(tmp) + 1 << endl;
    }
  }
}