#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
int PREV[N], a[N];
struct node {
  int val;
  node *l, *r;
  node() { l = r = NULL; }
  node(int val, node *l, node *r) : val(val), l(l), r(r) {}
};
node *root[N];
node *build(int s, int e) {
  if (s > e) return NULL;
  if (s == e) {
    return new node(0, NULL, NULL);
  }
  int m = (s + e) >> 1;
  node *left = build(s, m);
  node *right = build(m + 1, e);
  return new node(left->val + right->val, left, right);
}
node *upd(node *t, int s, int e, int idx, int x) {
  if (s == e) {
    return new node(t->val + x, NULL, NULL);
  }
  int m = (s + e) >> 1;
  if (idx <= m) {
    node *left = upd(t->l, s, m, idx, x);
    return new node(left->val + t->r->val, left, t->r);
  }
  node *right = upd(t->r, m + 1, e, idx, x);
  return new node(right->val + t->l->val, t->l, right);
}
int query(node *t, int s, int e, int l, int r) {
  if (s > e || l > e || r < s) return 0;
  if (l <= s && r >= e) return t->val;
  int m = (s + e) >> 1;
  return query(t->l, s, m, l, r) + query(t->r, m + 1, e, l, r);
}
int findnext(node *t, int s, int e, int k) {
  if (t->val <= k) return s;
  if (s == e) return n;
  int m = (s + e) >> 1;
  if (t->r->val > k)
    return findnext(t->r, m + 1, e, k);
  else if (t->r->val < k)
    return findnext(t->l, s, m, k - t->r->val);
  int ret = m + 1;
  int ret1 = findnext(t->l, s, m, 0);
  return min(ret, ret1);
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    PREV[a[i]] = 0;
  }
  root[0] = build(1, n);
  for (int i = 1; i <= n; i++) {
    if (PREV[a[i]] == 0) {
      root[i] = upd(root[i - 1], 1, n, i, 1);
    } else {
      root[i] = upd(root[i - 1], 1, n, PREV[a[i]], -1);
      root[i] = upd(root[i], 1, n, i, 1);
    }
    PREV[a[i]] = i;
  }
  for (int k = 1; k <= n; k++) {
    int ans = 0;
    for (int i = n; i >= 1;) {
      i = findnext(root[i], 1, n, k) - 1;
      ans++;
    }
    printf("%d ", ans);
  }
  printf("\n");
  return 0;
}
