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

/**
 *    created: 12.07.2020 00:19:34
 **/
#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
// #include <boost/multiprecision/cpp_int.hpp>
// using bint = boost::multiprecision::cpp_int;
using namespace std;
#define int long long
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pcnt(bit) __builtin_popcountll(bit)
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
const long double pi = acos(-1.0);
const int MAX = 1000010;
const int INF = 1LL << 60;
const int MOD = 1000000007;
// const int MOD = 998244353;

int modpow(int a, int n, int mod) {
  int ret = 1;
  while (n) {
    if (n & 1)
      ret *= a;
    a *= a;
    a %= mod;
    ret %= mod;
    n >>= 1;
  }
  return ret;
}

void f(int n, int &ret) {
  if (n == 0)
    return;
  else {
    ret++;
    return f(n % (pcnt(n)), ret);
  }
}

signed main() {

  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int n;
  cin >> n;
  string s;
  cin >> s;

  reverse(all(s));
  int popcnt = 0;
  rep(i, n) if (s[i] == '1') popcnt++;

  int val0 = 0, val1 = 0;

  // 0 -> 1
  int t0 = 1, mod0 = popcnt + 1;
  if (mod0 != 1 && mod0 != 0) {
    rep(i, n) {
      if (s[i] == '1') {
        val0 += t0;
        val0 %= mod0;
      }
      t0 *= 2;
      t0 %= mod0;
    }
  }

  // 1 -> 0
  int t1 = 1, mod1 = popcnt - 1;
  if (mod1 != 1 && mod1 != 0) {
    rep(i, n) {
      if (s[i] == '1') {
        val1 += t1;
        val1 %= mod1;
      }
      t1 *= 2;
      t1 %= mod1;
    }
  }

  vector<int> ret;

  rep(i, n) {
    int val;
    // 0 -> 1
    if (s[n - i - 1] == '0') {
      if (mod0 == 1) {
        ret.push_back(1);
        continue;
      }
      if (mod0 == 0) {
        ret.push_back(0);
        continue;
      }
      int dif = modpow(2, n - i - 1, mod0);
      val = val0 + dif;
      val %= mod0;
      if (val < 0)
        val += mod0;
    }
    // 1 -> 0
    else {
      if (mod1 == 1) {
        ret.push_back(1);
        continue;
      }
      if (mod1 == 0) {
        ret.push_back(0);
        continue;
      }
      int dif = modpow(2, n - i - 1, mod1);
      val = val1 - dif;
      val %= mod1;
      if (val < 0)
        val += mod1;
    }

    if (val == 0) {
      ret.push_back(1);
      continue;
    }
    int ans = 1;
    f(val, ans);
    ret.push_back(ans);
  }

  rep(i, n) cout << ret[i] << endl;
  return 0;
}

Error: TLE

Fixed submission:

/**
 *    created: 11.07.2020 21:14:10
 **/
#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
// #include <boost/multiprecision/cpp_int.hpp>
// using bint = boost::multiprecision::cpp_int;
using namespace std;
#define int long long
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pcnt(bit) __builtin_popcountll(bit)
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
const long double pi = acos(-1.0);
const int MAX = 1000010;
const int INF = 1LL << 60;
const int MOD = 1000000007;
// const int MOD = 998244353;

int count(int n, int &ret) {
  if (n == 0)
    return ret;
  else {
    ret++;
    return count(n % (pcnt(n)), ret);
  }
}

signed main() {

  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int n;
  cin >> n;
  string s;
  cin >> s;
  vector<char> v(n);
  int cnt0 = 0;
  rep(i, n) {
    v[i] = s[i];
    if (s[i] == '1')
      cnt0++;
  }
  reverse(all(v));
  vector<int> ret;
  rep(i, n) {
    int val = 0;
    int t = 1;
    int we = 0;
    int cnt = cnt0;
    if (v[n - i - 1] == '1')
      cnt--;
    else {
      cnt++;
      we = 1;
    }
    if (cnt == 0) {
      ret.push_back(0);
      continue;
    }
    if (cnt == 1) {
      ret.push_back(1);
      continue;
    }
    rep(j, n) {
      if (j == n - i - 1) {
        if (we == 1) {
          val += t;
          val %= cnt;
        }
      } else {
        if (v[j] == '1') {
          val += t;
          val %= cnt;
        }
      }
      t *= 2;
      t %= cnt;
    }
    int retu = 0;
    if (val == 0)
      ret.push_back(1);
    else
      ret.push_back(count(val, retu) + 1);
  }
  rep(i, n) cout << ret[i] << endl;
  return 0;
}