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 in Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)

import java.util.*;
import java.util.Map.Entry;
import static java.util.Comparator.reverseOrder;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;

import java.io.*;


@SuppressWarnings("unchecked")
public class Main{
   public static void main(String[] args){
        FastScanner fsc = new FastScanner();
        int n=fsc.nextInt();
        int[] nummap=new int[n];
        for(int i=0;i<n;i++) nummap[fsc.nextInt()-1]++;
        int[] num=new int[n+1];
        for(int i=0;i<n;i++) num[nummap[i]]++;
        TreeMap<Integer, Integer> tm=new TreeMap<>(reverseOrder());
        for(int i=1;i<=n;i++) if(num[i]>0) tm.put(i, num[i]);
        StringBuilder sb=new StringBuilder();
        for(int m=1;m<=n;m++){
            int k=m;
            TreeMap<Integer, Integer> now=(TreeMap<Integer, Integer>) tm.clone();
            int cnt=0;
            // System.out.println(m);
            Out:while(true){
                // for(Entry<Integer, Integer> et:now.entrySet()){
                //     for(int i=0;i<et.getValue();i++){
                //         System.out.print(et.getKey()+" ");
                //     }
                // }
                // System.out.println();
                TreeMap<Integer, Integer> next=new TreeMap<>(reverseOrder());
                In:while(true){
                    Entry<Integer, Integer> e=now.pollFirstEntry();
                    if(isNull(e)) break Out;
                    int key=e.getKey();
                    int val=e.getValue();
                    if(val<k){
                        k-=val;
                        if(key>1) next.put(key-1, val);
                    } else{
                        Integer v=next.putIfAbsent(key, val-k);
                        if(nonNull(v)) next.put(key, v+val-k);
                        if(key>1) next.put(key-1, k+(now.containsKey(key-1)?now.get(key-1):0));
                        break In;
                    }
                }
                while(!next.isEmpty()){
                    Entry<Integer, Integer> e=next.pollFirstEntry();
                    now.put(e.getKey(), e.getValue());
                }
                k=m;
                cnt++;
            }
            // System.out.println();
            sb.append(cnt).append('\n');
        }
        System.out.print(sb);
   }
}

class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public long nextLong() {
        if (!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while(true){
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }
    public double nextDouble() { return Double.parseDouble(next());}
}