Problem:
 Score : 600 points    Problem Statement  Takahashi has N cards. The i -th of these cards has an integer A_i written on it.  Takahashi will choose an integer K , and then repeat the following operation some number of times:   Choose exactly K cards such that the integers written on them are all different, and eat those cards. (The eaten cards disappear.)   For each K = 1,2, \ldots, N , find the maximum number of times Takahashi can do the operation.      Constraints   1 \le N \le 3 \times 10^5  1 \le A_i \le N  All values in input are integers.         Input  Input is given from Standard Input in the following format:  N  A_1  A_2  \ldots  A_N       Output  Print N integers.
The t -th (1 \le t \le N) of them should be the answer for the case K=t .        Sample Input 1 3
2 1 2      Sample Output 1 3
1
0  For K = 1 , we can do the operation as follows:   Choose the first card to eat.  Choose the second card to eat.  Choose the third card to eat.   For K = 2 , we can do the operation as follows:   Choose the first and second cards to eat.   For K = 3 , we cannot do the operation at all. Note that we cannot choose the first and third cards at the same time.       Sample Input 2 5
1 2 3 4 5      Sample Output 2 5
2
1
1
1       Sample Input 3 4
1 3 3 3      Sample Output 3 4
1
0
0

Solution (Python):
N = int(input())
A = list(map(int, input().split()))

C = [0] * N
D = [0] * (N + 1)
for a in A:
    C[a - 1] += 1
    D[C[a - 1]] += 1

S = [0] * (N + 1)
for i in range(N):
    S[i + 1] = S[i] + D[i + 1]

ans = N
for K in range(1, N + 1):
    while ans > 0 and S[ans] < K * ans:
        ans -= 1
    print(ans)

Solution (Python):
import sys
input = sys.stdin.readline

def I(): return int(input())
def MI(): return map(int, input().split())
def LI(): return list(map(int, input().split()))

"""
とりあえず，数字ではなく，数字の出現回数C[i]を持つ．

Kが変化すると色々と変わるので，Kごとに見ようとすると割と大変そう，1つのkごとにO(N)すらかけられない，というか計算大変そう．
(カードがT種類あるとして，k>Tは全部0だったりする．Kの区間に対して一気に答えを出す方法はありそう．)

食べる回数をmとして，mごとに最大のKを求める．

m回食べるということは，各数字につき最大m回までしか食べられないということ
食べられる枚数の総数はΣ(min(m,C[i]))．このときの最大のKは，総数//m

C[i]を昇順に並べておけば二分探索で
min(m,C[i])=C[i]の範囲がわかり，累積和をとっておればこの区間の合計がO(1)で求まる
"""
def main():
    import bisect
    
    N=I()
    A=LI()
    from collections import defaultdict
    dd = defaultdict(int)
    
    for i in range(N):
        dd[A[i]]+=1
        
    L=[]
    for k,v in dd.items():
        L.append(v)
        
    L.sort()
    nl=len(L)
    S=[0]*(nl+1)
    for i in range(nl):
        S[i+1]=S[i]+L[i]
        
    ans=[0]*(N+1)
    
    for m in range(1,N+1):
        temp=0
        num=bisect.bisect_left(L,m)
        temp+=S[num]
        temp+=(nl-num)*m
        
        maxk=temp//m
        ans[maxk]=max(ans[maxk],m)
        
        
    
        
    M=0
    for i in range(N,-1,-1):
        M=max(M,ans[i])
        ans[i]=M
        
    for i in range(1,N+1):
        print(ans[i])
        
        
        
    
    

main()

Solution (Python):
from collections import defaultdict

N = int(input())
A = list(map(int, input().split()))
d = defaultdict(lambda: 0)
for a in A:
    d[a] += 1
cant_use = [0] * (N+1)
for v in d.values():
    for i in range(v):
        cant_use[i] += v - i


def is_ok(i, k):
    return (N-cant_use[i])/k >= i

def bisect(ng, ok, k):
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid, k):
            ok = mid
        else:
            ng = mid
    return ok

for k in range(1, N + 1):
    print(bisect(N+1, 0, k))

Solution (Python):
from collections import Counter
import bisect


def main():
    N = int(input())
    A = list(map(int, input().split()))
    count_list = list(Counter(A).values())
    count_list.sort()
    cumsum_count = [0] * len(count_list)
    cumsum_count[0] = count_list[0]
    for i in range(1, len(count_list)):
        cumsum_count[i] = cumsum_count[i - 1] + count_list[i]
    ans_list = [0] * N
    n_max = N
    for k in range(1, len(count_list) + 1):
        
        
        
        n_max = min(n_max, N // k)
        s = 0
        while True:
            
            index = bisect.bisect_left(count_list, n_max)
            s = n_max * (len(count_list) - index)
            
            if index > 0:
                s += cumsum_count[index - 1]
            if s >= k * n_max or n_max == 0:
                break
            n_max -= 1
        ans_list[k - 1] = n_max
    for ans in ans_list:
        print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
def main():
    N = int(input())
    A = list(map(int, input().split()))
    C = [0] * (N+1)
    Cnt_A = [0] * (N+1)
    for a in A:
        Cnt_A[a] += 1
        cnt = Cnt_A[a]
        C[cnt] += 1
    cum_C = []
    cu = 0
    for c in C:
        cu += c
        cum_C.append(cu)
    Ans = []
    for k in range(1, N+1):
        
        
        
        ok, ng = 0, N//k+1
        while ok + 1 < ng:
            n = ok+ng>>1
            if cum_C[n] >= n*k:
                ok = n
            else:
                ng = n
        Ans.append(ok)
    print("\n".join(map(str, Ans)))

main()

Solution (Python):
from collections import Counter
n = int(input())
a = list(map(int, input().split()))
c = list(Counter(a).values())
c.sort()

ans = n
cnt = 0
for i in range(n):
    m = i + 1 - cnt
    while c and c[-1] > ans // m:
        ans -= c.pop()
        cnt += 1
        m -= 1
    print(ans // m)

Solution (Python):
from collections import Counter
from itertools import accumulate
n = int(input())
A = tuple(map(int, input().split()))
C = Counter(A)
D = [0]*(n+1)
for v in C.values():
  D[v] += 1
E = tuple(accumulate(k*d for k, d in enumerate(D)))
D = tuple(accumulate(D))
F = [0]*(n+1)
for x in range(1, n+1):
  temp = (E[x] + x*(D[n]-D[x])) // x
  F[x] = temp
for k in range(1, n+1):
  ok = 0
  ng = n+1
  while ng-ok > 1:
    mid = (ok+ng)//2
    if k <= F[mid]:
      ok = mid
    else:
      ng = mid
  print(ok)

Solution (Python):
import sys
input = sys.stdin.readline

N = int(input())
A = list(map(int, input().split()))
cnt = [0]*(N+1)
B = [0]*(N+1)

for Ai in A:
    cnt[Ai] += 1
    B[cnt[Ai]] += 1

acc = [0]

for Bi in B:
    acc.append(acc[-1]+Bi)

x = N

for K in range(1, N+1):
    while x>0 and K*x>acc[x+1]:
        x -= 1
    
    print(x)

Solution (Python):
from bisect import *
N=int(input())
A=list(map(int,input().split()))
B=[0]*(N+1)
for i in range(N):
  B[A[i]]+=1
C=[0]*(N+1)
for i in range(N+1):
  C[B[i]]+=1
D=[0]
E=[0]
for i in range(N+1):
  D.append(D[i]+i*C[i])
  E.append(E[i]+C[-i-1])
E=E[::-1]
F=[]
for i in range(1,N+1):
  F.append((D[i+1]//i)+E[i+1])
F=F[::-1]
for i in range(N):
  print(N-bisect_left(F,i+1))

Solution (Python):
def main():
    N = int(input())
    A = list(map(int, input().split()))

    
    C = [0] * (N + 1)
    D = [0] * (N + 1)
    for a in A:
        C[a] += 1
        D[C[a]] += 1

    
    
    

    
    
    
    
    
    
    
    
    
    
    
    

    
    
    
    
    
    
    

    
    
    
    

    
    
    
    S = [0] * (N + 1)
    f = [0] * (N + 1)
    for x in range(1, N+1):
        S[x] = S[x-1] + D[x]
        f[x] = S[x] // x

    ans = []
    prev_ans = N
    for K in range(1, N+1):
        a = prev_ans
        while True:
            if f[a] >= K or a == 0:
                break
            a -= 1
        ans.append(a)
        prev_ans = a

    print(*ans, sep='\n')

if __name__ == '__main__':
    main()

Solution (Python):
import sys
from collections import Counter
input = sys.stdin.readline
N = int(input())
a = list(map(int, input().split()))
c = Counter()
for x in a: c[x] += 1
cv = Counter()
for v in c.values(): cv[v] += 1


def check(x, K):
  t = 0
  for k, v in cv.items(): t += min(k, x) * v
  return t >= K * x

res = [N] * (N + 1)
for K in range(1, N):
  ok = 0
  ng = res[K] + 1
  while ng - ok > 1:
    m = (ok + ng) // 2
    if check(m, K + 1): ok = m
    else: ng = m
  res[K + 1] = ok

for r in res[1: ]: print(r)

Solution (Python):
import bisect

n = int(input())
k = sorted(map(int, input().split()))

hist = []
count = 0
for i in range(n):
    count += 1
    if i == n - 1 or k[i] != k[i + 1]:
        hist.append(count)
        count = 0
hist.sort()

sumh = [0]
for i in range(len(hist)):
    sumh.append(sumh[-1] + hist[i])

def ok(h, d):
    i = bisect.bisect_left(hist, h)
    s = sumh[i] + h * (len(hist) - i)
    return s >= h * d

def binary_search(d):
    lo, hi = 0, n // d + 1
    while hi - lo > 1:
        mid = (lo + hi) // 2
        if ok(mid, d):
            lo = mid
        else:
            hi = mid
    return lo

for d in range(1, n + 1):
    print(binary_search(d))

Solution (Python):
def main():
    from sys import stdin
    input = stdin.readline
    from collections import Counter as ct
    from bisect import bisect_left as bl

    n = int(input())
    max_a = sorted(ct(list(map(int, input().split()))).values())
    now_a = [i for i in max_a]
    m = len(max_a)
    cnt = m
    ans = 0
    ans_list = [0]*(n-m)

    for use in range(m, 1, -1):
        rest = ans
        nex = now_a[0]
        while rest:
            val = nex
            start = bl(now_a, val+1)
            nex += 1
            q = max(-1, start-1-rest, bl(max_a, now_a[start-1]+1)-1)
            for i in range(start-1, q, -1):
                now_a[i] += 1
            if now_a[start-1] == 1:
                cnt += start-1-q
            rest -= start-1-q
            if start != m:
                nex = now_a[start]
        while cnt >= use:
            ans += 1
            rest = use
            nex = now_a[-1]
            end = m
            while rest:
                val = nex
                start = bl(now_a, val)
                if start != 0:
                    nex = now_a[start-1]
                end = min(end, bl(now_a, val+1), start+rest)
                for i in range(start, end):
                    now_a[i] -= 1
                if now_a[start] == 0:
                    cnt -= end-start
                rest -= end-start
                end = start
        ans_list.append(ans)
    print(n)
    for i in ans_list[::-1]:
        print(i)


main()

Solution (Python):
def main():
    from sys import stdin
    input = stdin.readline
    from collections import Counter as ct
    from bisect import bisect_left as bl

    n = int(input())
    max_a = sorted(ct(list(map(int, input().split()))).values())
    now_a = [i for i in max_a]
    m = len(max_a)
    cnt = m
    ans = 0
    ans_list = [0]*(n-m)

    for use in range(m, 1, -1):
        rest = ans
        nex = now_a[0]
        while rest:
            val = nex
            start = bl(now_a, val+1)
            nex += 1
            q = max(-1, start-1-rest, bl(max_a, now_a[start-1]+1)-1)
            for i in range(start-1, q, -1):
                now_a[i] += 1
            if now_a[start-1] == 1:
                cnt += start-1-q
            rest -= start-1-q
            if start != m:
                nex = now_a[start]
        while cnt >= use:
            ans += 1
            rest = use
            nex = now_a[-1]
            end = m
            while rest:
                val = nex
                start = bl(now_a, val)
                if start != 0:
                    nex = now_a[start-1]
                end = min(end, bl(now_a, val+1), start+rest)
                for i in range(start, end):
                    now_a[i] -= 1
                if now_a[start] == 0:
                    cnt -= end-start
                rest -= end-start
                end = start
        ans_list.append(ans)
    print(n)
    for i in ans_list[::-1]:
        print(i)


main()

Solution (Python):
def main():
    from collections import Counter as ct
    from bisect import bisect_left as bl

    n = int(input())
    max_a = sorted(ct(list(map(int, input().split()))).values())
    now_a = [i for i in max_a]
    m = len(max_a)
    cnt = m
    ans = 0
    ans_list = []

    for use in range(n, 0, -1):
        rest = ans
        nex = now_a[0]
        
        while rest:
            val = nex
            start = bl(now_a, val+1)
            nex += 1
            for i in range(start-1, -1, -1):
                if now_a[i] == max_a[i]:
                    if start != m:
                        nex = now_a[start]
                    break
                elif now_a[i] == 0:
                    cnt += 1
                now_a[i] += 1
                rest -= 1
                if rest == 0:
                    break
        
        while True:
            if cnt < use:
                ans_list.append(ans)
                break
            ans += 1
            rest = use
            nex = now_a[-1]
            end = m
            while rest:
                val = nex
                start = bl(now_a, val)
                if start != 0:
                    nex = now_a[start-1]
                for i in range(start, end):
                    if now_a[i] > val:
                        break
                    elif now_a[i] == 1:
                        cnt -= 1
                    now_a[i] -= 1
                    rest -= 1
                    if rest == 0:
                        break
                end = start
    for i in ans_list[::-1]:
        print(i)


main()

Solution (Python):
from collections import Counter
def main():
    N = int(input())
    A = list(map(int, input().split()))
    m = max(list(Counter(A).values()))
    d = Counter(Counter(A).values())
    l = []
    t = 0
    for i in range(m, 0, -1):
        t += d[i]
        l.append(t)
    l.reverse()
    t = 0
    r = []
    for i in range(N):
        if m > i:
            t += l[i]
        r.append(t//(i+1))
    p = -1
    a = []
    for i, v in enumerate(reversed(r)):
        if p != v:
            a.append((v, N-i))
        p = v
    a.append((N, 0))
    t = 0
    aa = []
    for i in range(1, N+1):
        if a[t][0] < i:
            t += 1
        aa.append(a[t][1])
    for i in aa:
        print(i)
main()

Solution (Python):
N = int(input())
A = list(map(int,input().split()))
C = [0] * (N + 1)
for a in A:
    C[a] += 1
D = [0] * (N + 1)
for c in C:
    D[c] += 1
P = [0] * (N + 1)
Q = [0] * (N + 1)
for i in range(1, N+1):
    P[i] = P[i-1] + i * D[i]
    Q[i] = Q[i-1] + D[i]
F = [0] * (N + 1)
for i in range(1, N+1):
    F[i] = int((P[i] + i * (Q[N] - Q[i])) / i)
index = N
for i in range(1, N+1):
    while True:
        if index == 0:
            print(0)
            break
        if F[index] >= i:
            print(index)
            break
        else:
            index -= 1

Solution (Python):
import sys
readline = sys.stdin.readline
sys.setrecursionlimit(10**7)
def readstr():return readline().rstrip().decode()
def readstrs():return list(readline().decode().split())
def readint():return int(readline())
def readints():return list(map(int,readline().split()))
def printrows(x):print('\n'.join(map(str,x)))

from collections import Counter
from itertools import accumulate
import bisect

n = readint()
a = readints()
b = sorted(Counter(a).values())
exist = len(b)
b = [0]*(n-exist)+b
c = list(accumulate([0]+b))

ans = [n]
for k in range(2,exist+1):
    l = 0
    r = n//k+1
    while r-l>1:
        x = (r+l)//2
        i = bisect.bisect_left(b,x)
        if c[i]+(n-i)*x>=x*k:
            l = x
        else:
            r = x
    ans.append(l)

printrows(ans+[0]*(n-exist))

Solution (Python):
import sys

readline = sys.stdin.buffer.readline
sys.setrecursionlimit(10**7)
def readstr():return readline().rstrip().decode()
def readstrs():return list(readline().decode().split())
def readint():return int(readline())
def readints():return list(map(int,readline().split()))
def printrows(x):print('\n'.join(map(str,x)))

from collections import Counter
from itertools import accumulate
import bisect

n = readint()
a = readints()
b = sorted(Counter(a).values())
exist = len(b)
b = [0]*(n-exist)+b
c = list(accumulate([0]+b))

ans = [n]
for k in range(2,exist+1):
    l = 0
    r = n//k+1
    while r-l>1:
        x = (r+l)//2
        i = bisect.bisect_left(b,x)
        if c[i]+(n-i)*x>=x*k:
            l = x
        else:
            r = x
    ans.append(l)

printrows(ans+[0]*(n-exist))

Solution (Python):
from collections import Counter
from itertools import accumulate
import bisect

printRows = lambda x:print('\n'.join(map(str,x)))

n = int(input())
a = list(map(int, input().split()))
b = sorted(Counter(a).values())
exist = len(b)
b = [0]*(n-exist)+b
c = list(accumulate([0]+b))

ans = [n]
for k in range(2,exist+1):
    l = 0
    r = n//k+1
    while r-l>1:
        x = (r+l)//2
        i = bisect.bisect_left(b,x)
        if c[i]+(n-i)*x>=x*k:
            l = x
        else:
            r = x
    ans.append(l)

printRows(ans+[0]*(n-exist))

Solution (Python):
from collections import Counter
from itertools import accumulate
import bisect

printRows = lambda x:print('\n'.join(map(str,x)))

n = int(input())
a = list(map(int, input().split()))
b = sorted(Counter(a).values())
exist = len(b)
b = [0]*(n-exist)+b
c = list(accumulate([0]+b))

ans = [n]
for k in range(2,n+1):
    l = 0
    r = n//k+1
    while r-l>1:
        x = (r+l)//2
        i = bisect.bisect_left(b,x)
        if c[i]+(n-i)*x>=x*k:
            l = x
        else:
            r = x
    ans.append(l)

printRows(ans)

Solution (Python):
from collections import Counter
from itertools import accumulate
import bisect

printRows = lambda x:print('\n'.join(map(str,x)))

n = int(input())
a = list(map(int, input().split()))
b = sorted(Counter(a).values())
exist = len(b)
b = [0]*(n-exist)+b
c = list(accumulate([0]+b))

ans = [n]
for k in range(2,n//2+1):
    if k>exist:
        ans.append(0)
        continue
    l = 0
    r = n//k+1
    while r-l>1:
        x = (r+l)//2
        i = bisect.bisect_left(b,x)
        if c[i]+(n-i)*x>=x*k:
            l = x
        else:
            r = x
    ans.append(l)

for k in range(max(n//2+1,2),n+1):
    if exist>=k:
        ans.append(1)
    else:
        ans.append(0)

printRows(ans)

Solution (Python):
from collections import Counter
from itertools import accumulate
import bisect

n = int(input())
a = list(map(int, input().split()))
b = sorted(Counter(a).values())
exist = len(b)
b = [0]*(n-exist)+b
c = list(accumulate([0]+b))

print(n)
for k in range(2,n//2+1):
    l = 0
    r = n+1
    while r-l>1:
        x = (r+l)//2
        i = bisect.bisect_left(b,x)
        if c[i]+(n-i)*x>=x*k:
            l = x
        else:
            r = x
    print(l)

for k in range(max(n//2+1,2),n+1):
    if exist>=k:
        print(1)
    else:
        print(0)

Solution (Python):
import sys
from collections import Counter
readline = sys.stdin.readline

N = int(readline())
A = list(map(int, readline().split()))


table = Counter()
for a in A:
    table[a] += 1

table = list(table.values())
table.sort(reverse = True)
L = len(table)
ata = table[:] + [0]
for i in range(1, L):
    ata[i] += ata[i-1]


vm = [-1]*(N+2)
for med in range(N, 0, -1):
    idx = -1
    for v in range(max(0, vm[med+1]), L):
        if table[v] <= med:
            break
        idx = v
    vm[med] = idx
Ans = [None]*N
for k in range(1, N+1):
    ok = 0
    ng = N//k+1
    while abs(ok-ng) > 1:
        med = (ok+ng)//2
        res = N - ata[vm[med]] + med*(vm[med]+1)
        if res >= k*med:
            ok = med
        else:
            ng = med
    Ans[k-1] = ok
print('\n'.join(map(str, Ans)))

Solution (Python):
from collections import Counter
n = int(input())
c = list(Counter(ai for ai in map(int, input().split())).values())
c.sort()

clen = len(c)

s = [0] * (clen + 1)
for i in range(clen):
    s[i + 1] = s[i] + c[i]

for i in range(1, n + 1):
    rest = clen - i
    if rest < 0:
        print(0)
        continue
    l1 = 0
    r1 = s[clen] // i + 2
    while r1 - l1 > 1:
        c1 = (l1 + r1) // 2

        l2 = -1
        r2 = clen
        while r2 - l2 > 1:
            c2 = (r2 + l2) // 2
            if c[c2] < c1:
                l2 = c2
            else:
                r2 = c2

        if (r2 - rest) * c1 <= s[r2]:
            l1 = c1
        else:
            r1 = c1
    print(l1)

Solution (Python):
import bisect,copy

N=int(input())
A=list(map(int,input().split()))

data=[0 for i in range(0,N+1)]
for i in range(0,N):
    data[A[i]]+=1

X=[]
for i in range(0,N+1):
    if data[i]!=0:
        X.append(data[i])

X.sort()
n=len(X)
Y=copy.copy(X)
for i in range(1,n):
    Y[i]+=Y[i-1]

ans={i:0 for i in range(0,N+1)}
ans[0]=float('inf')

for i in range(1,N+1):
    index=bisect.bisect_left(X,i+1)
    if index!=0:
        t=Y[index-1]+(n-index)*i
    else:
        t=(n-index)*i
    ans[i]=t//i


pointer=N
i=1
while N+1>i:
    if ans[pointer]>=i:
        print(pointer)
        i+=1
    else:
        pointer-=1

Solution (Python):
import sys
stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
nn = lambda: list(stdin.readline().split())
ns = lambda: stdin.readline().rstrip()

import bisect
from collections import Counter

n = ni()
a = na()

c = sorted(Counter(a).values())
cc = [0]
m = len(c)
for i in c:
    cc.append(cc[-1]+i)

def is_ok(k,arg):
    b = bisect.bisect_right(c,arg)
    p = cc[b] + (m-b)*arg
    return True if p >= arg*k else False

for k in range(1,n+1):
    if k > m:
        print(0)
        continue
    
    ok,ng = -1,n//k+1
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(k,mid):
            ok = mid
        else:
            ng = mid
    
    print(ok)

Solution (Python):
from collections import Counter
from itertools import accumulate
import bisect
n = int(input())
a = list(map(int,input().split()))
c = list(Counter(a).items())
c = list(list(zip(*c))[1])
c.sort()
xls = [0]*(n+1)
for i in range(1,n+1):
  geqx = len(c)-bisect.bisect_left(c,i)
  xls[i] = xls[i-1]+geqx
xlsacc = list(accumulate(xls))
for k in range(1,n+1):
  l = 0
  r = n+1
  while l+1<r:
    x = (l+r)//2
    if k*x <= xls[x]:
      l = x
    else:
      r = x
  print(l)

Solution (Python):
n=int(input())
l=list(map(int,input().split()))
import collections
c=collections.Counter(l)
l=[0]+list(c.values())
c=collections.Counter(l)
l=list(c.items())
l.sort()
l.append((n,0))
acc=[0 for i in range(n+2)]
for i,j in l:
    acc[i]+=j
for i in range(1,n+1):
    acc[-i-1]+=acc[-i]
ans=[0 for i in range(n+1)]
t=0
for i,j in zip(l,l[1:]):
    a,b=i
    c,d=j
    t+=a*b
    for i in range(a+1,c+1):
        for j in range(acc[i+1],acc[i]+t//i+1):
            ans[j]=i
for i in ans[1:]:
    print(i)

Solution (Python):
from collections import Counter

n = int(input())
a = list(map(int, input().split()))
c = Counter(a)
d = Counter(c.values())

dx = [0 for _ in range(n+1)]
for i in range(1, n+1):
	dx[i] = dx[i-1] + i*d[i]

xdx = [0 for _ in range(n+2)]
xdx[n] = d[n]
for i in range(n-1, 0, -1):
	xdx[i] = xdx[i+1] + d[i]

res = [0] + [(dx[i] + i*xdx[i+1]) // i for i in range(1, n+1)]
ans = [0 for _ in range(n)]
cur = n
for i in range(n):
	while cur > 0 and res[cur] < i+1:
		cur -= 1
	if cur > 0:
		ans[i] = cur
print(*ans, sep="\n")

Solution (Python):
from itertools import accumulate

N, *A = map(int, open(0).read().split())

C = [0] * (N + 1)
D = [0] * (N + 1)
for a in A:
    C[a] += 1
    D[C[a]] += 1

T = [0] + [s // i for i, s in enumerate(accumulate(D[1:]), 1)]

ans = []
x = N
for k in range(1, N + 1):
    while 0 < x and T[x] < k:
        x -= 1
    ans.append(x)

print("\n".join(map(str, ans)))

Solution (Python):
import sys
input = sys.stdin.readline
from collections import Counter

N = int(input())
A = list(map(int, input().split()))

C = sorted(list(Counter(A).values()), reverse=True)
L = len(C)
B = []

num = C[0]
for i, c in enumerate(C):
    for _ in range(num-c):
        B.append(i)
    num = c
for _ in range(num):
    B.append(L)

ans = [N]
for n in range(2, N+1):
    if n > L:
        ans.append(0)
        continue
    count = 0
    stack = []
    for b in B:
        tmp = b
        while stack:
            if tmp >= n:
                last = stack.pop()
                tmp = tmp + last - n
                count += 1
            else:
                break
        count += tmp//n
        stack.append(tmp%n)
    ans.append(count)

print(*ans, sep='\n')

Solution (Python):
from bisect import bisect_left

N = int(input())
A = list(map(int, input().split()))

lst = [0] * (N)
for a in A:
    lst[a - 1] += 1
lst.sort() 

s = [0] * (N + 1)
for i in range(N):
    s[i + 1] = s[i] + lst[i]










ans = N
i = N
for k in range(1, N + 1):
    while True:
        while  i >= 1 and lst[i - 1] >= ans:
            i -= 1
        total = ans * (N - i) + s[i]
        if total >= ans * k:
            break
        ans -= 1
    
    print (ans)

Solution (Python):
from bisect import bisect_left

N = int(input())
A = list(map(int, input().split()))

lst = [0] * (N + 1)
for a in A:
    lst[a - 1] += 1
lst.sort() 

s = [0] * (N + 1)
for i in range(N):
    s[i + 1] = s[i] + lst[i + 1]




def check(x, k):
    i = bisect_left(lst, x) - 1
    total = x * (N - i) + s[i]
    return total >= x * k

ans = N
for k in range(1, N + 1):
    while True:
        if check(ans, k):
            break
        ans -= 1
    print (ans)

Solution (Python):
from bisect import bisect_left

N = int(input())
A = list(map(int, input().split()))

lst = [0] * (N + 1)
for a in A:
    lst[a - 1] += 1
lst.sort() 

s = [0] * (N + 1)
for i in range(N):
    s[i + 1] = s[i] + lst[i + 1]




def check(x, k):
    i = bisect_left(lst, x) - 1
    total = x * (N - i) + s[i]
    return total >= x * k


for k in range(1, N + 1):
    l = 0 
    r = N // k + 1 
    while l + 1 < r:
        c = (l + r) // 2
        if check(c, k):
            l = c
        else:
            r = c
    print (l)

Solution (Python):
N = int(input())
A = list(map(int,input().split()))
from collections import Counter
from bisect import bisect
vs = list(Counter(A).values())
vs.sort()
cums = [0]
for v in vs:
    cums.append(cums[-1] + v)

def is_ok(k,m):
    j = bisect(vs,m)
    z = cums[j] + m*(len(vs)-j)
    return z >= m*k

ans = []
for k in range(1,N+1):
    if k > len(vs):
        ans.append(0)
    else:
        ok = 0
        ng = N//k + 1
        while ng-ok > 1:
            m = (ok+ng)//2
            if is_ok(k,m):
                ok = m
            else:
                ng = m
        ans.append(ok)

print(*ans, sep='\n')

Solution (Python):
N = int(input())
A = list(map(int,input().split()))
from collections import Counter
from bisect import bisect
vs = list(Counter(A).values())
vs.sort()
cums = [0]
for v in vs:
    cums.append(cums[-1] + v)

def is_ok(k,m):
    j = bisect(vs,m)
    z = cums[j] + m*(len(vs)-j)
    return z >= m*k

ans = []
for k in range(1,N+1):
    if k > len(vs):
        ans.append(0)
    else:
        ok = 0
        ng = N//k + 1
        while ng-ok > 1:
            m = (ok+ng)//2
            if is_ok(k,m):
                ok = m
            else:
                ng = m
        ans.append(ok)

print(*ans, sep='\n')

Solution (Python):
from collections import Counter
N = int(input())
C = sorted(list(Counter(map(int, input().split())).values()))

rest = N
removed = 0
for K in range(1, N + 1):
    d = K - removed
    while C and C[- 1] > rest//d:
        rest -= C[- 1]
        C.pop()
        removed += 1
        d -= 1
    print(rest//d)

Solution (Python):


import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))
"""
.2分探索を考える
.各kに対してx回以上抜き出せるかという問いを考える
.各数の個数を数えて数iの個数をCiとする
.各数iを抜き出せるのはCiまで
 ⇒各数を抜き出す回数min(Ci,x)
.Σmin(Ci,x)はkx以上でなければいけない(k個x回抜き出すため)
.これを満たすときx回抜き出せる
.このままではO(n^2(logn))なので工夫する
.Σ(min(Ci,x))はk依存でないのでここを工夫する(Σ(min(Ci,x))をSxとする)
.SxはSx-1と比べてx以上のCiの数だけ増える(x以上のCiの数をDxとする)
.Sx := Sx-1 + Dx
.Dxを求める時はCのリストについてbisectを行う。
⇒Ciの個数のリストdを用意してdの累積和を用意しておくとO(n)
.Sx >= k*xとなるxの最大値を2分探索で求める。(O(nlogn))
⇒変形すると,Sx/x >= kであり、各kに対してSx/xは単調減少なのでO(n)
"""
n = I()
a = LI()
cnt = list(Counter(a).values())
d = [0]*(n+1)
for i in cnt:
    d[i] += 1
d = list(accumulate(d))
m = d[-1]
S = [0]*(n+1)
for i in range(1,n+1):
    S[i] = S[i-1] + (m - d[i-1]) 
S2 = [0]*(n+1)
for i in range(1,n+1):
    S2[i] = S[i]//i
tmp = n
for k in range(1,n+1):
    while S2[tmp] < k:
        tmp -= 1
        if tmp <= 0:
            print(0)
            break
    else:
        print(tmp)

Solution (Python):


import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))
"""
.2分探索を考える
.各kに対してx回以上抜き出せるかという問いを考える
.各数の個数を数えて数iの個数をCiとする
.各数iを抜き出せるのはCiまで
 ⇒各数を抜き出す回数min(Ci,x)
.Σmin(Ci,x)はkx以上でなければいけない(k個x回抜き出すため)
.これを満たすときx回抜き出せる
.このままではO(n^2(logn))なので工夫する
.Σ(min(Ci,x))はk依存でないのでここを工夫する(Σ(min(Ci,x))をSxとする)
.SxはSx-1と比べてx以上のCiの数だけ増える(x以上のCiの数をDxとする)
.Sx := Sx-1 + Dx
.Dxを求める時はCのリストについてbisectを行う。
.Sx >= k*xとなるxの最大値を2分探索で求める。(O(nlogn))
"""
n = I()
a = LI()
cnt = list(Counter(a).values())
cnt.sort()
m = len(cnt)
S = [0]*(n+1)
for x in range(1,n+1):
    l = bl(cnt,x)
    S[x] = S[x-1] + (m-l)
for k in range(1,n+1):
    high,low = n+1,0
    while high - low > 1:
        mid = (high + low)//2
        if S[mid] >= k*mid:
            low = mid
        else:
            high = mid
    print(low)

Solution (Python):
import sys
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7
input=lambda:sys.stdin.readline().rstrip()

def bisection(l,r,f,left=True,discrete=True):
    eps=1 if(discrete) else 10**-8
    if((not left)^f(r)): return r if(left) else r+1
    elif(left^f(l)): return l-1 if(left) else l
    while(r-l>eps):
        h=(l+r)//2 if(discrete) else (l+r)/2
        if((not left)^f(h)): l=h
        else: r=h
    return (l+r)/2 if(not discrete) else l if(left) else r

from collections import defaultdict
from bisect import bisect_left
def resolve():
    n=int(input())
    D=defaultdict(int)
    for a in map(int,input().split()):
        D[a]+=1

    D=list(D.values())
    D.sort()
    t=len(D)
    S=[0]*(t+1)
    for i in range(t):
        S[i+1]=S[i]+D[i]

    k=0
    def check(t):
        
        i=bisect_left(D,t)
        score=S[i]+t*(len(D)-i)
        return score>=k*t

    for k in range(1,n+1):
        print(bisection(0,n//k+1,check))
resolve()

Solution (Python):
from collections import Counter as C
N = int(input())
A = sorted(list(C([int(a) for a in input().split()]).values()))
X = [0] * 303030
for a in A:
    X[a] += 1

s = 0
c = 0
B = [0] * 303030
for i in range(300030)[::-1]:
    s += c
    B[i] += s
    c += X[i]

def chk(k, a):
    if N - B[a] >= k * a: return 1
    return 0

for i in range(1, N+1):
    l, r = 0, N + 1
    while r-l > 1:
        m = (l+r) // 2
        if chk(i, m):
            l = m
        else:
            r = m
    print(l)

Solution (Python):
from collections import Counter
from itertools import accumulate
N = int(input())
As = map(int, input().split())
xs = [0] + sorted([x for x in Counter(As).values()]) + [10**18]
Xs = accumulate(xs)
M = len(xs)-2
rs = [0]*N
mn = N+1
for l, (x, X) in enumerate(zip(xs[1:], Xs)):
    l = M-l
    k = X//(x+1)+l+1
    if x <= X//(k-l):
        k+=1
    for i in range(k, mn):
        rs[i-1] = X//(i-l)
    mn = min(k, mn)
for r in rs:
    print(r)