Problem p02609 (C++) — buggy submission, verdict: Time Limit Exceeded

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

long long modpow(long long base, long long power, long long modvalue) {
  base %= modvalue;
  long long res = 1;
  while (power > 0) {
    if (power & 1)
      res = res * base % modvalue;
    base = base * base % modvalue;
    power >>= 1;
  }
  return res;
}

long long get_modpow_value(string &s, long long ones) {
  long long n = s.size();
  long long modpow_value = 0;
  for (long long i = 0; i < n; i++) {
    if (s[i] == '1') {
      modpow_value += modpow(2, n - i - 1, ones);
      modpow_value %= ones;
    }
  }

  return modpow_value % ones;
}

int main() {
  long long n;
  string s;
  cin >> n >> s;

  long long ones = 0;
  for (long long i = 0; i < n; i++) {
    if (s[i] == '1') {
      ones += 1;
    }
  }
  long long possible_rem1 = 0, possible_rem2 = 0;
  if (ones > 1)
    possible_rem1 = get_modpow_value(s, ones - 1);
  if (ones >= 0)
    possible_rem2 = get_modpow_value(s, ones + 1);

  for (long long i = 0; i < n; i++) {
    long long current_ones = ones;
    long long rem;
    if (s[i] == '0') {
      current_ones += 1;
      rem = possible_rem2 + modpow(2, n - 1 - i, current_ones);
      rem %= current_ones;
    } else {
      current_ones -= 1;
      if (current_ones == 0) {
        cout << 0 << endl;
        continue;
      }
      rem = possible_rem1 - modpow(2, n - 1 - i, current_ones);
      rem = (current_ones + (rem % current_ones)) % current_ones;
    }

    long long res = 1;
    while (rem != 0) {
      res += 1;
      rem = rem % __builtin_popcount(rem);
    }
    cout << res << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

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

int modpow(int base, int power, int modvalue) {

  if (power == 0)
    return 1;

  if (power & 1) {
    int current_value = modpow(base, power - 1, modvalue);
    return ((current_value % modvalue) * (base % modvalue)) % modvalue;
  } else {
    int current_value = modpow(base, power / 2, modvalue);
    return ((current_value % modvalue) * (current_value % modvalue)) % modvalue;
  }
}

int get_modpow_value(string &s, int ones) {
  int n = s.size();
  int modpow_value = 0;
  for (int i = 0; i < n; i++) {
    if (s[i] == '1') {
      modpow_value += modpow(2, n - i - 1, ones);
      modpow_value %= ones;
    }
  }

  return modpow_value % ones;
}

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

  int ones = 0;
  for (int i = 0; i < n; i++) {
    if (s[i] == '1') {
      ones += 1;
    }
  }
  int possible_rem1 = 0, possible_rem2 = 0;
  if (ones > 1)
    possible_rem1 = get_modpow_value(s, ones - 1);
  if (ones >= 0)
    possible_rem2 = get_modpow_value(s, ones + 1);

  for (int i = 0; i < n; i++) {
    int current_ones = ones;
    int rem;
    if (s[i] == '0') {
      current_ones += 1;
      rem = possible_rem2 + modpow(2, n - 1 - i, current_ones);
      rem %= current_ones;
    } else {
      current_ones -= 1;
      if (current_ones == 0) {
        cout << 0 << endl;
        continue;
      }
      rem = possible_rem1 - modpow(2, n - 1 - i, current_ones);
      // while(rem < 0){
      // rem += current_ones;
      //}
      // rem %= current_ones;
      rem = (current_ones + (rem % current_ones)) % current_ones;
    }

    int res = 1;
    while (rem != 0) {
      // cout << "REM : " << rem << "POPCOUNT : " << __builtin_popcount(rem);
      res += 1;
      rem = rem % __builtin_popcount(rem);
    }
    cout << res << endl;
  }

  return 0;
}