#include #include #include using namespace std; struct vrchol { vrchol *syn[26], *otec; int index_halda; vrchol(vrchol* otec=NULL) : otec(otec) { index_halda=-1; memset(syn, 0, sizeof(syn)); } }; struct zaznam { vrchol *trie_vrchol; string nazev; int pocet; zaznam(vrchol *tv, string n, int p) : trie_vrchol(tv), nazev(n), pocet(p) { } }; struct trie { vrchol *root; trie() { root = new vrchol(); } vrchol *find(const string &S) { // Najde a je-li třeba, vytvoří vrchol odpovídající řetězci S vrchol *kde = root; for (unsigned i=0; isyn[idx]) kde->syn[idx] = new vrchol(kde); kde = kde->syn[idx]; } return kde; } }; bool operator< (const zaznam &A, const zaznam &B) { if (A.pocet != B.pocet) return A.pocet < B.pocet; return A.nazev > B.nazev; } struct halda_a_trie { trie T; vector H; // halda void vymen(int x, int y) { // Vymění v haldě záznamy na pozicích x a y, zároveň patřičně upraví trie vrchol *tx = H[x].trie_vrchol, *ty = H[y].trie_vrchol; swap(H[x],H[y]); tx->index_halda = y; ty->index_halda = x; } int uprav_haldu(int x) { // Přesouvá prvek x nahoru nebo dolů podle potřeby, dokud není halda OK while (true) { int y=x; if (x>0 && H[(x-1)/2]index_halda==-1) { kde->index_halda=H.size(); H.push_back(zaznam(kde,nazev,0)); } H[ kde->index_halda ].pocet += add; int x = uprav_haldu(kde->index_halda); // Pokud jsme zmenšili počet na nulu, vymažeme záznam z haldy if (H[x].pocet==0) { vymen(x,H.size()-1); H[H.size()-1].trie_vrchol->index_halda=-1; H.pop_back(); uprav_haldu(x); } } }; int main() { halda_a_trie HT; int zmena; string nazev; while (cin >> zmena >> nazev) { HT.update(nazev,zmena); if (HT.H.empty() || HT.H[0].pocet==0) cout << endl; else cout << HT.H[0].nazev << " " << HT.H[0].pocet << endl; } return 0; }