Problem:
Score : 400 points

Problem Statement

Let \mathrm{popcount}(n) be the number of 1s in the binary representation of n.
For example, \mathrm{popcount}(3) = 2, \mathrm{popcount}(7) = 3, and \mathrm{popcount}(0) = 0.

Let f(n) be the number of times the following operation will be done when we repeat it until n becomes 0: "replace n with the remainder when n is divided by \mathrm{popcount}(n)." (It can be proved that, under the constraints of this problem, n always becomes 0 after a finite number of operations.)

For example, when n=7, it becomes 0 after two operations, as follows:

\mathrm{popcount}(7)=3, so we divide 7 by 3 and replace it with the remainder, 1.

\mathrm{popcount}(1)=1, so we divide 1 by 1 and replace it with the remainder, 0.

You are given an integer X with N digits in binary.
For each integer i such that 1 \leq i \leq N, let X_i be what X becomes when the i-th bit from the top is inverted.
Find f(X_1), f(X_2), \ldots, f(X_N).

Constraints

1 \leq N \leq 2 \times 10^5

X is an integer with N digits in binary, possibly with leading zeros.

Input

Input is given from Standard Input in the following format:

N
X

Output

Print N lines. The i-th line should contain the value f(X_i).

Sample Input 1

3
011

Sample Output 1

2
1
1

X_1 = 7, which will change as follows: 7 \rightarrow 1 \rightarrow 0. Thus, f(7) = 2.

X_2 = 1, which will change as follows: 1 \rightarrow 0. Thus, f(1) = 1.

X_3 = 2, which will change as follows: 2 \rightarrow 0. Thus, f(2) = 1.

Sample Input 2

23
00110111001011011001110

Sample Output 2

2
1
2
2
1
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
1
3

Solution in C (GCC 9.2.1) (judge verdict: Runtime Error)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>

#define SIZE 200005
#define PI acosl(-1) //3.14159265358979323846264338327950L 
#define rep(i, N) for (i = 0; i < N; i++) //制御変数iを用いてN回転
#define array(N, t) (t*)calloc(N, sizeof(t)) //t型N要素の1次元配列を動的確保後0クリア(freeを忘れずに)
#define zero(a); {int iter; rep(iter, sizeof(a)/sizeof((a)[0])) (a)[iter]=0;} //1次元配列aのゼロ初期化?
#define Sort(a, t) qsort(a, sizeof(a)/sizeof((a)[0]), sizeof(t), comp) //compを使って1次元配列をソート

typedef long long ll; typedef long double ld;
typedef struct node { int data; struct node *next; } Node;

Node *list[SIZE];
int queue[SIZE]; int q_head = 0, q_tail = 0;

void print_log(); //とりあえず文字を出力してどこまで実行できているか確認(for debug)
void printa_int(int *a, int size); //int型の1次元配列aを出力(for debug)
void printl_int(int size); //リンクリストを出力(for debug)
int comp(const void *a, const void *b); //昇順並び替えに使う比較関数
Node* add_node(int i, int data); void free_list(Node* head);
int queue_empty(); int queue_full();
void enqueue(int data); int dequeue();
ll* factorize(ll N); //Nを素因数分解、得られる配列は素因数,指数,素因数,…となっている(添字はintで指定する必要あり?)
void check_factorization(ll *fact); //素因数分解を表示(for debug)

int f(int n) {
    if (n == 0) return 0;
    int popcount = __builtin_popcount(n);
    return 1 + f(n % popcount);
}

int main() {
    int i, N, popcount = 0, pop, b;
    char s[SIZE];
    scanf("%d %s", &N, s);
    int *X = array(N, int);
    int *count = array(N, int);
    rep(i, N) {
        X[i] = s[i] - '0';
        popcount += X[i];
    }

    // popcountが増えるか減るかの2通りを試す
    rep(b, 2) {
        pop = (b == 0) ? (popcount + 1) : (popcount - 1);
        // 元の数をpopcountで割った余りを求める
        int r0 = 0;
        rep(i, N) {
            r0 = (r0 << 1) % pop;
            r0 += X[i];
        }
        //下の桁から余りの変化を見る
        int r, k = 1;
        for (i = N - 1; i >= 0; i--) {
            if (X[i] == b) {
                if (b == 0) r = (r0 + k) % pop;
                else r = (r0 - k + pop) % pop;
                count[i] = f(r) + 1;
            }
            k = (k << 1) % pop;
        }
    }

    rep(i, N) printf("%d\n", count[i]);

    free(X);
    free(count);
    return 0;
}

void print_log() {
    printf("=== print log ===\n");
}
void printa_int(int *a, int size) {
    int i;
    printf("[");
    for (i = 0; i < size; i++)
        printf("%d, ", a[i]);
    printf("]\n");
}
void printl_int(int size) {
    int i;
    Node *t;
    rep(i, size) {
        printf("[%d] ", i);
        for (t = list[i]; t; t = t->next) printf("%d, ", t->data);
        printf("\n");
    }
}
int comp(const void *a, const void *b) {
    return *(int*)a - *(int*)b;
}
Node* add_node(int i, int data) {
    if (!list[i]) {
        list[i] = (Node*)malloc(sizeof(Node*));
        list[i]->data = data;
    } else {
        Node *t;
        t = list[i];
        list[i] = (Node*)malloc(sizeof(Node*));
        list[i]->data = data;
        list[i]->next = t;
    }
    return list[i];
}
void free_list(Node* head) {
    Node *prev = NULL, *t = head;
    while (t) {
        prev = t;
        t = t->next;
        free(prev);
    }
}
int queue_empty() {
    return q_head == q_tail;
}
int queue_full() {
    return (q_head - 1) % SIZE == q_tail % SIZE;
}
void enqueue(int data) {
    if (queue_full()) {
        printf("full!\n");
        return;
    }
    queue[q_tail++] = data;
    q_tail %= SIZE;
}
int dequeue() {
    if (queue_empty()) {
        printf("empty!\n");
        return -444444;
    }
    int data = queue[q_head++];
    q_head %= SIZE;
    return data;
}
ll* factorize(ll N) {
    ll *res = array(((sqrt(N) + 1) * 2), ll);
    ll i, x = N;
    int count = 0;
    for (i = 2; i * i <= N; i++) {
        ll e = 0;
        while (x % i == 0) {
            x /= i;
            e++;
        }
        if (e > 0) {
            res[count * 2] = i;
            res[count * 2 + 1] = e;
            count++;
        }
    }
    if (x > 1) {
        res[count * 2] = x;
        res[count * 2 + 1] = 1;
    }
    return res;
}
void check_factorization(ll *fact) {
    int i = 1;
    printf("%lld^%lld", fact[0], fact[1]);
    while (fact[i * 2] > 0) {
        printf(" * %lld^%lld", fact[i * 2], fact[i * 2 + 1]);
        i++;
    }
    printf("\n");
}