#include #include using namespace std; struct trie { struct vrchol { int pocet; int max; vrchol *otec; vrchol *syn[26]; vrchol() { pocet = max = 0; otec = NULL; memset(syn, 0, sizeof(syn)); } }; vrchol *root; trie() { root = new vrchol(); } void update(const string &S, int add) { // Najdeme a je-li třeba, vytvoříme odpovídající vrchol vrchol *kde = root; for (unsigned i=0; isyn[idx]) { kde->syn[idx] = new vrchol(); kde->syn[idx]->otec = kde; } kde = kde->syn[idx]; } // Upravíme uloženou hodnotu a přepočítáme maxima kde->pocet += add; while (kde) { kde->max = kde->pocet; for (int i=0; i<26; i++) if (kde->syn[i] && kde->syn[i]->max > kde->max) kde->max = kde->syn[i]->max; kde = kde->otec; } } void vypis_max() { vrchol *kde = root; int max = root->max; // Následujeme maximum a vypisujeme přitom řetězec while (kde->pocet != max) { int i = 0; while (!kde->syn[i] || kde->syn[i]->max != max) i++; cout << (char)('a' + i); kde = kde->syn[i]; } cout << ' ' << max << endl; } }; int main() { trie T; int zmena; string nazev; while (cin >> zmena >> nazev) { T.update(nazev,zmena); T.vypis_max(); } return 0; }