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

#include <iostream>
#include <string>
#include <vector>

int main() {
  int n;
  int sum = 0;
  std::string S;
  std::cin >> n >> S;
  for (int i = 0; i < n; i++) {
    if (S[i] == '1')
      sum++;
  }

  // 例外処理
  if (sum == 0) {
    for (int i = 0; i < n; i++) {
      std::cout << 1 << std::endl;
    }
    return 0;
  }
  if (sum == 1) {
    std::vector<int> count_p1(n);
    count_p1[0] = 1; // 1 % 2
    for (int i = 1; i < n; i++) {
      count_p1[i] = (count_p1[i - 1] * 2) % 2;
    }
    int r_p1 = 0;
    for (int i = 0; i < n; i++) {
      if (S[i] == '1') {
        r_p1 += count_p1[n - 1 - i];
        r_p1 %= 2;
      }
    }
    for (int i = 0; i < n; i++) {
      int r = 0;
      if (S[i] == '1') {
        std::cout << 0 << std::endl;
        continue;
      } else {
        r = r_p1;
        r += count_p1[n - 1 - i];
        r %= 2;
      }

      int cnt = 1;
      while (r > 0) {
        // popcountの計算
        int x = r;
        int popcount = 0;
        while (x > 0) {
          if (x % 2 == 1)
            popcount++;
          x /= 2;
        }

        r %= popcount;
        cnt++;
      }

      std::cout << cnt << std::endl;
    }

    return 0;
  }

  // 2^iの剰余
  std::vector<int> count_p1(n), count_m1(n);
  count_p1[0] = 1 % (sum + 1);
  count_m1[0] = 1 % (sum - 1);
  for (int i = 1; i < n; i++) {
    count_p1[i] = (count_p1[i - 1] * 2) % (sum + 1);
    count_m1[i] = (count_m1[i - 1] * 2) % (sum - 1);
  }

  // Xに対して事前の剰余計算
  int r_p1 = 0, r_m1 = 0;
  for (int i = 0; i < n; i++) {
    if (S[i] == '1') {
      r_p1 += count_p1[n - 1 - i];
      r_m1 += count_m1[n - 1 - i];
      r_p1 %= sum + 1;
      r_m1 %= sum - 1;
    }
  }

  // 後は愚直に
  for (int i = 0; i < n; i++) {
    int r = 0;
    if (S[i] == '1') {
      // sum - 1の剰余で, 2^(n - 1- i)桁目が消える
      r = r_m1;
      r -= count_m1[n - 1 - i];
      while (r < 0) {
        r += sum - 1;
      }
    } else {
      r = r_p1;
      r += count_p1[n - 1 - i];
      r %= sum + 1;
    }

    int cnt = 1;
    while (r > 0) {
      // popcountの計算
      int x = r;
      int popcount = 0;
      while (x > 0) {
        if (x % 2 == 1)
          popcount++;
        x /= 2;
      }

      r %= popcount;
      cnt++;
    }

    std::cout << cnt << std::endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <string>
#include <vector>

namespace mp = boost::multiprecision;

int n;
int sum = 0;
std::string S;

int f(int sum, std::string n) {
  int cnt = 0;
  std::vector<int> sum2;
  int tmp = sum;
  while (tmp > 0) {
    sum2.push_back(tmp % 2);
    tmp /= 2;
  }

  while (1) {
    // nからsumを何回引けるか

    cnt++;
  }
  return cnt;
}

int main() {
  std::cin >> n >> S;
  mp::cpp_int x = 0, base = 1;
  for (int i = 0; i < n; i++) {
    if (S[i] == '1')
      sum++;
    if (S[n - 1 - i] == '1') {
      x += base;
    }
    base *= 2;
  }

  base /= 2;

  for (int i = 0; i < n; i++) {
    if (S[i] == '1') {
      x -= base;
      sum--;
    } else {
      x += base;
      sum++;
    }

    mp::cpp_int y = x;
    int cnt = 0;
    mp::cpp_int tmp = sum;
    while (y > 0) {
      y %= tmp;
      mp::cpp_int z = y;
      tmp = 0;
      while (z > 0) {
        tmp += z % 2;
        z /= 2;
      }
      cnt++;
    }

    std::cout << cnt << std::endl;

    if (S[i] == '1') {
      x += base;
      sum++;
    } else {
      x -= base;
      sum--;
    }
    base /= 2;
  }
  return 0;
}