Informatyczny kącik olimpijski
Magic
Tym razem omówimy zadanie z pierwszego dnia Pierwszej Olimpiady Informatycznej Juniorów (EJOI), która odbyła się w Sofii we wrześniu 2017 roku.
Zadanie. Dane jest słowo o długości w którym występuje różnych liter alfabetu angielskiego. Magicznym podsłowem nazywamy niepuste podsłowo (czyli spójny fragment słowa), które zawiera taką samą liczbę wystąpień każdej z liter. Należy policzyć liczbę magicznych podsłów w słowie Podsłowa, które są takie same, ale znajdują się na różnych pozycjach, uznajemy za różne.
Na potrzeby tego artykułu przyjmijmy dodatkowe założenie, że słowo zawiera wyłącznie litery ze zbioru -początkowych liter alfabetu angielskiego. Aby uzyskać to założenie, wystarczy po wczytaniu słowa nadać literom nowe identyfikatory będące kolejnymi małymi literami alfabetu angielskiego.
Rozwiązanie .
Najprostsze rozwiązanie polega na rozpatrzeniu każdego podsłowa niezależnie. Aby sprawdzić, czy dane podsłowo jest magiczne, należy zliczyć liczbę wystąpień każdej litery w podsłowie, a następnie sprawdzić, czy wszystkie otrzymane wartości są równe.
Liczba wszystkich podsłów jest rzędu Sprawdzenie, czy podsłowo jest magiczne, wymaga operacji. Zatem całe rozwiązanie wykonuje operacji.
Rozwiązanie .
Powyższe rozwiązanie można w łatwy sposób przyspieszyć. Każdą z możliwych początkowych pozycji podsłowa słowa rozpatrzymy niezależnie. Załóżmy, że rozpatrujemy początkową pozycję Przeiterujemy wszystkie potencjalne końce podsłów zaczynających się na tej pozycji. Niech będzie aktualnie rozpatrywanym podsłowem. Zauważmy, że aby policzyć liczbę wystąpień poszczególnych liter w tym podsłowie, wystarczy skorzystać z wyniku dla podsłowa oraz zaktualizować go o wystąpienie litery Zatem, dla ustalonego podsłowa potrafimy wyznaczyć te wartości w stałej liczbie operacji Natomiast sprawdzenie, czy dane podsłowo jest magiczne, wymaga operacji (należy sprawdzić, czy liczba wystąpień każdej z liter jest taka sama). Zauważmy, że słowa, których długość nie jest podzielna przez na pewno nie są magiczne. Zatem dla tych słów możemy pominąć fazę sprawdzania liczności poszczególnych liter. Słów, dla których wykonamy fazę sprawdzania liczności liter, jest Sumarycznie wykonamy operacji.
Przypadek dla
Przypadek dla jest trywialny. Każde podsłowo jest magiczne, zatem wynikiem jest
Przypadek dla
Najpierw słowo zamieńmy na ciąg liczb Pierwszą literę słowa oraz wszystkie jej wystąpienia zamieńmy na Pozostałe litery zamieńmy na Zauważmy teraz, że każde magiczne podsłowo ma sumę
Policzmy sumy prefiksowe gdzie dla Zauważmy, że podsłowo jest magiczne, jeśli czyli jeśli Wystarczy zatem policzyć liczbę par indeksów, dla których sumy prefiksowe są równe. W tym celu zliczmy wystąpienia elementów w ciągu Niech oznacza liczbę wystąpień w ciągu Wówczas wynikiem jest Rozwiązanie wykonuje operacji.
Rozwiązanie .
Zacznijmy od przypisania każdej literze jej unikalnego identyfikatora ze zbioru Następnie przekształćmy słowo na ciąg liczb zamieniając każdą literę na odpowiadający jej identyfikator. Np. słowo kajak możemy zamienić na ciąg (a otrzymało identyfikator k otrzymało identyfikator zaś j otrzymało identyfikator ). Od teraz będziemy operowali na ciągu liczb naturalnych.
Niech:
- będzie równe jeśli na -tej pozycji występuje wartość oraz 0 w przeciwnym przypadku;
- (liczba wystąpień wartości na -elementowym prefiksie ciągu );
- ; (wektor reprezentuje liczbę wystąpień poszczególnych liter na -elementowym prefiksie ciągu );
Podsłowo jest magiczne, jeśli:
dla pewnego Po przekształceniach, które pozostawiam Czytelnikowi jako ćwiczenie, otrzymujemy równoważną definicję magicznego podsłowa:
Zatem każda taka para że oznacza magiczne podsłowo. Policzmy zatem, ile jest par takich samych wektorów w ciągu W tym celu posortujmy ten ciąg leksykograficznie. Wówczas wektory, które są równe, będą tworzyły spójny blok. Spośród bloku takich samych wektorów można wybrać par.
Obliczenie wektorów dla każdego wymaga operacji, zaś sortowanie operacji. Zatem całe rozwiązania wykonuje operacji.