Problem p02890 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <cassert>
#include <iostream>
#include <list>
#include <map>
using namespace std;
int main() {
  int n;
  cin >> n;
  map<int, int> m;
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    m[a]++;
  }
  map<int, int> m2;
  for (auto &x : m)
    m2[x.second]++;
  int sz = 0;
  for (auto &x : m2)
    sz += x.second;
  for (int t = 1; t <= n; t++) {
    list<pair<int, int>> tmp(m2.begin(), m2.end());
    int ans = 0, cursz = sz;
    // cerr << "t = " << t  << endl;
    while (cursz >= t) {
      // for (auto &x : tmp) cerr << x.first << ' ' << x.second << endl;
      // cerr << "ans = " << ans << endl;
      auto it = prev(tmp.end());
      int t1 = t;
      for (;;) {
        if (t1 > it->second)
          t1 -= it->second, it--;
        else {
          if (it->first == 1) {
            if (it->second == t1)
              it = tmp.erase(it);
            else {
              it->second -= t1;
              it++;
            }
            cursz -= t1;
          } else {
            if (it == tmp.begin() || (prev(it)->first != it->first - 1)) {
              tmp.insert(it, {it->first - 1, t1});
            } else
              prev(it)->second += t1;
            it->second -= t1;
            it++;
          }
          while (it != tmp.end()) {
            assert(it->first != 1);
            if (it != tmp.begin() && prev(it)->first == it->first - 1) {
              prev(it)->second += it->second;
              it = tmp.erase(it);
            } else {
              it->first--;
              it++;
            }
          }
          break;
        }
      }
      ans++;
    }
    cout << ans << endl;
  }
}


Fixed submission:
#include <cassert>
#include <iostream>
#include <list>
#include <map>
using namespace std;
int main() {
  int n;
  cin >> n;
  map<int, int> m;
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    m[a]++;
  }
  map<int, int> m2;
  for (auto &x : m)
    m2[x.second]++;
  int sz = 0;
  for (auto &x : m2)
    sz += x.second;
  for (int t = 1; t <= n; t++) {
    if (sz < t) {
      cout << 0 << endl;
      continue;
    }
    list<pair<int, int>> tmp(m2.begin(), m2.end());
    int ans = 0, cursz = sz;
    // cerr << "t = " << t  << endl;
    while (cursz >= t) {
      // for (auto &x : tmp) cerr << x.first << ' ' << x.second << endl;
      // cerr << "ans = " << ans << endl;
      auto it = prev(tmp.end());
      int t1 = t;
      for (;;) {
        if (t1 > it->second)
          t1 -= it->second, it--;
        else {
          if (it->first == 1) {
            if (it->second == t1)
              it = tmp.erase(it);
            else {
              it->second -= t1;
              it++;
            }
            cursz -= t1;
          } else {
            if (it == tmp.begin() || (prev(it)->first != it->first - 1)) {
              tmp.insert(it, {it->first - 1, t1});
            } else
              prev(it)->second += t1;
            it->second -= t1;
            it++;
          }
          while (it != tmp.end()) {
            assert(it->first != 1);
            if (it != tmp.begin() && prev(it)->first == it->first - 1) {
              prev(it)->second += it->second;
              it = tmp.erase(it);
            } else {
              it->first--;
              it++;
            }
          }
          break;
        }
      }
      ans++;
    }
    cout << ans << endl;
  }
}