Topics

The key challenge in this problem is to figure out, for each , the maximum number of times (let’s denote it by ) we can pick exactly distinct cards before running out of valid options.

Idea

Reformulating the Problem

  1. We have distinct integers overall, and for each distinct integer , we know its frequency
  2. We want to form disjoint groups, each of size , where each group has distinct integers

The distinctness requirement implies that if we want to form such groups, each integer can contribute at most times overall (because you cannot use the same integer more than once in the same group, but you can reuse it in different groups).

Hence, the feasibility condition for a given is:

If this sum is large enough, we can form groups each of size .

Binary Search Over

To find the maximum valid , we can binary-search over possible values of . Let’s denote:

  • the sorted frequencies
  • A prefix sum array where =

We check feasibility with:

Instead of computing the sum of naively, we note:

  • All contribute exactly
  • All contribute exactly

Sort . If is the smallest index such that , then

Using prefix sums and a binary search ( in the code) on the frequencies, we can compute this in . Doing that for each up to is acceptable given the constraints.

Edge Cases

  • : We can take every card on its own, so the answer is simply the sum of all frequencies
  • : Impossible to form a group of size if there aren’t distinct integers

Complexity

  • Building the frequency array and prefix sums:
  • For each , we do a binary search in
  • Overall, for all from 1 to

Code

import sys
import bisect
from collections import Counter
 
 
def max_partitions(items_dict, k, prefix_sums, counts):
    # Handle edge cases
    if k <= 0 or k > len(items_dict):
        return 0
 
    # Special case for k=1
    if k == 1:
        return sum(items_dict.values())
 
    n = len(items_dict)
 
    def can_form_partitions(p):
        idx = bisect.bisect_right(counts, p)
        available_items = p * (n - idx) + prefix_sums[idx]
        return available_items >= p * k
 
    # Binary search for the maximum valid number of partitions
    left, right = 0, prefix_sums[n] // k
    result = 0
 
    while left <= right:
        mid = (left + right) // 2
        if can_form_partitions(mid):
            result = mid
            left = mid + 1
        else:
            right = mid - 1
 
    return result
 
 
def solve(N, arr):
    items_dict = Counter(arr)
    counts = sorted(list(items_dict.values()))
    n = len(counts)
 
    # Precompute prefix sums
    prefix_sums = [0] * (n + 1)
    for i in range(n):
        prefix_sums[i + 1] = prefix_sums[i] + counts[i]
 
    for i in range(1, N+1):
        ans = max_partitions(items_dict, i, prefix_sums, counts)
        print(ans)
 
 
def main():
    n = int(sys.stdin.readline().strip())
    arr = list(map(int, sys.stdin.readline().strip().split()))
    solve(n, arr)
 
 
if __name__ == "__main__":
    main()