IV Obóz Naukowy ILOCAMP Część algorytmiczna
Transkrypt
IV Obóz Naukowy ILOCAMP Część algorytmiczna
J. Bujnowska A. Jaskółka Ł. Jocz M. Litwin J. Tomasiewicz I Liceum Ogólnokształcące im. Adama Mickiewicza w Białymstoku Podlaskie Stowarzyszenie na Rzecz Uzdolnionych IV Obóz Naukowy ILOCAMP Część algorytmiczna Kadra informatyczna: Joanna Bujnowska Ireneusz Bujnowski Adrian Jaskółka Joachim Jelisiejew Łukasz Jocz Mateusz Litwin Jacek Tomasiewicz (koordynator) Główni organizatorzy: Iwona Bujnowska Ireneusz Bujnowski Joachim Jelisiejew Jacek Tomasiewicz Serwy, 25 września – 1 października 2011 (wydanie pierwsze) ISBN 978-83-930856-5-1 Niniejsze wydanie książki ukazuje się dzięki: inicjatywie i działaniom Olimpiady Informatycznej, środkom finansowym firmy Google, wsparciu Ośrodka Edukacji Informatycznej i Zastosowań Komputerów. Spis treści 1 Wstęp 7 I 9 Grupa początkująca 2 Zadania 2.1 Dzień próbny . Liczba . . . . . 2.2 Dzień pierwszy Stopki . . . . . Sumy i różnice . Szuflady . . . . Samochody . . 2.3 Dzień drugi . . Konik polny . . Kwadrat . . . . Zakład . . . . . Odległość . . . 2.4 Dzień trzeci . . Konik polny 2 . Las . . . . . . . Przegrody . . . Gwoździe . . . 2.5 Dzień czwarty . Tabliczka . . . Długa taśma . . Krany . . . . . Drabina . . . . 2.6 Dzień piąty . . Figury . . . . . Zbiór . . . . . . Dwie wieże . . Miasta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 11 11 12 12 13 14 15 16 16 17 18 19 20 20 21 22 23 24 24 25 26 27 28 28 29 30 31 3 Rozwiązania 33 3.1 Dzień próbny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.2 Dzień pierwszy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3 SPIS TREŚCI 3.3 3.4 3.5 3.6 Dzień Dzień Dzień Dzień 4 Wykłady 4.1 Wstęp 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 II SPIS TREŚCI drugi . trzeci . czwarty piąty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . do grafów . . . . . . . Czym jest graf? . . . . Najważniejsze pojęcia Rodzaje grafów . . . . Reprezentacja grafu . . Przeszukiwanie grafu . Proste ćwiczenia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 42 48 53 . . . . . . . 59 59 59 59 60 61 63 64 Grupa średnio zaawansowana 5 Zadania 5.1 Dzień próbny . Odważniki . . . 5.2 Dzień pierwszy Drzewko . . . . Wesoła małpka Dzieci . . . . . 5.3 Dzień drugi . . Zapałki . . . . Losy . . . . . . Budowla . . . . 5.4 Dzień trzeci . . Wycinek . . . . Pasy ruchu . . . Banki . . . . . 5.5 Dzień czwarty . Gra . . . . . . . Grzybki . . . . Radiotelegraf . 5.6 Dzień piąty . . Sadzenie bulw . Hodowla . . . . Szklanki . . . . 6 Rozwiązania 6.1 Dzień próbny . 6.2 Dzień pierwszy 6.3 Dzień drugi . . 6.4 Dzień trzeci . . 6.5 Dzień czwarty . 6.6 Dzień piąty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 67 67 69 69 71 72 73 73 74 75 77 77 78 79 80 80 81 82 83 83 84 86 . . . . . . 87 87 89 93 99 105 110 SPIS TREŚCI SPIS TREŚCI 7 Wykłady 7.1 Operacje na bitach . . . . . . . . . . . . . . . . . . . . . . 7.1.1 Podstawowe operacje . . . . . . . . . . . . . . . . . 7.1.2 Zliczanie liczby zapalonych bitów (jedynek) . . . . 7.1.3 Zliczanie liczby zer wiodących i zer na końcu liczby 7.1.4 Znajdowanie najmniej znaczącego zapalonego bitu . 7.1.5 Ćwiczenia . . . . . . . . . . . . . . . . . . . . . . . III . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 115 115 116 117 117 118 Grupa olimpijska 119 8 Zadania 8.1 Dzień próbny . . . . . . . . Palindromy . . . . . . . . . 8.2 Dzień pierwszy . . . . . . . Halloween . . . . . . . . . . Chińczyk . . . . . . . . . . . Drzewa . . . . . . . . . . . . 8.3 Dzień drugi . . . . . . . . . Podciągi arytmetyczne . . . Robot . . . . . . . . . . . . Operacje . . . . . . . . . . . 8.4 Dzień trzeci . . . . . . . . . Drogi ekspresowe . . . . . . Obława . . . . . . . . . . . Trójmiasto . . . . . . . . . . 8.5 Dzień czwarty . . . . . . . . Punkty . . . . . . . . . . . . Wrogie państwa . . . . . . . RoboSort . . . . . . . . . . 8.6 Dzień piąty . . . . . . . . . Zmaksymalizowany podzbiór Sprężyny . . . . . . . . . . . Dolary i Euro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 . 121 . 121 . 123 . 123 . 125 . 126 . 128 . 128 . 129 . 130 . 131 . 131 . 133 . 135 . 136 . 136 . 137 . 138 . 140 . 140 . 141 . 142 . . . . . . 145 . 145 . 147 . 154 . 158 . 165 . 170 . . . . 177 . 177 . 177 . 177 . 178 9 Rozwiązania 9.1 Dzień próbny . 9.2 Dzień pierwszy 9.3 Dzień drugi . . 9.4 Dzień trzeci . . 9.5 Dzień czwarty . 9.6 Dzień piąty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Wykłady 10.1 Sztuczna inteligencja . . . . . . 10.1.1 Wstęp . . . . . . . . . . 10.1.2 Algorytmy dokładne . . 10.1.3 Algorytmy wykładnicze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SPIS TREŚCI SPIS TREŚCI 10.1.4 Algorytmy heurystyczne . . . . . . . . . . . . . . . . . . . . . . . . 178 10.1.5 Algorytmy hybrydowe . . . . . . . . . . . . . . . . . . . . . . . . . 182 10.1.6 Konkursy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 6 Rozdział 1 Wstęp Drogi Czytelniku! Oddajemy Ci do rąk książkę, która jest zbiorem zadań, rozwiązań i wykładów z tegorocznego obozu organizowanego przez I Liceum Ogólnokształcące w Białymstoku oraz Podlaskie Stowarzyszenie na Rzecz Uzdolnionych. Treści zadań z tej książki znajdują się również w serwisie http://main.edu.pl/, na tej stronie można też sprawdzić poprawność swojego rozwiązania w warunkach zbliżonych do obozowych. Na wstępie chcielibyśmy podziękować: • bankowi PKO BP za ufundowanie nagród dla najlepszych uczestników obozu, • Pani mgr Iwonie Bujnowskiej i Panu mgr Ireneuszowi Bujnowskiemu za organizację obozu i wszechstronne wsparcie, • Panu Joachimowi Jelisiejewowi za obsługę sprawdzarki obozowej oraz autorstwo i opracowanie części zadań, • Panu Tadeuszowi Kuranowi za pomoc i umożliwienie wydania tej książki, • Panu Michałowi Majewskiemu za autorstwo i opracowanie kilku zadań, • Pani mgr Annie Opalińskiej, polonistce w I Liceum Ogólnokształcącym, za korektę błędów językowych i stylistycznych, • Panu mgr Jakubowi Radoszewskiemu za udostępnienie serwisu http://main.edu.pl/ i pomocne rady, • Panu Dariuszowi Sosnowskiemu za autorstwo i opracowanie kilku zadań. Pierwszy obóz został zorganizowany we wrześniu 2008 z inicjatywy Ireneusza Bujnowskiego i Iwony Bujnowskiej. Od początku przybrał on formę tygodniowego wyjazdu, na którym uczestnicy rozwiązują zadania matematyczne i informatyczne wzorowane na zadaniach z licealnych olimpiad przedmiotowych. Tegoroczny obóz, organizowany w dniach 25 września – 1 października w hotelu Albatros w Serwach koło Augustowa, zgromadził ponad stu uczestników. 7 Obóz ma profil typowo naukowy. Rankami uczestnicy mierzą się z zadaniami, po południu, po przerwie na zajęcia sportowe, przeprowadzane są omówienia zadań oraz liczne wykłady. Rozkład dnia jest dość napięty, czas wolny obozowiczów to jedynie późny wieczór. Zadania, warsztaty i wykłady mają bardzo zróżnicowany poziom – najłatwiejsze dostosowane są do osób dopiero zaczynających naukę pozaszkolną, najtrudniejsze nastawione są na osoby uczestniczące w olimpiadach: obecnych oraz przyszłych finalistów i laureatów. Tradycyjnie kadrę naukową obozu stanowią byli olimpijczycy – studenci Uniwersytetu Warszawskiego. Obóz nie jest zamknięty dla osób z zewnątrz – uczestnikami są również uczniowie wielu liceów z całej Polski. We wrześniu 2012 planujemy zorganizować kolejny, piąty już obóz, na który serdecznie zapraszamy. Informacje na temat tego i innych obozów można znaleźć na stronie http://oboz.ilo.pl. Ewentualne uwagi oraz pytania prosimy przesyłać na adres mailowy: jacek [email protected]. Autorzy. 8 ROZDZIAŁ 2. ZADANIA 2.4. DZIEŃ TRZECI Zadanie: Gwoździe Autor zadania: Jacek Tomasiewicz Dostępna pamięć: 32 MB Dzień 3, 28.09.2011 Gwoździe Adam przybija do deski gwoździe. Przybił już wszystkie gwoździe na pewne wysokości, jednak nie ma czasu dalej się tym zajmować. Obok stoi Kozik i zastanawia się, jak przybić niektóre gwoździe, aby jak najwięcej było na tej samej wysokości. Zakładamy, że Kozik ma czas uderzyć tylko k razy młotkiem, przy czym Kozik ma taką siłę i precyzję, że jednym uderzeniem może wbić gwóźdź na dowolnie wybraną wysokość pomiędzy zerem a wysokością, na jaką aktualnie jest wbity gwóźdź. Wejście Pierwszy wiersz wejścia zawiera dwie liczby całkowite n, k (2 6 n, k 6 106 ), oznaczającą odpowiednio liczbę gwoździ oraz maksymalną liczbę uderzeń Kozika. Kolejny wiersz zawiera n liczb całkowitych w1 , w2 , . . . , wn (0 6 wi 6 109 ), gdzie wi oznacza wysokość, na jaką wbity jest i-ty gwóźdź. W testach wartych co najmniej 60% punktów zachodzi dodatkowy warunek n 6 103 . Wyjście Pierwszy i jedyny wiersz wyjścia powinien zawierać maksymalną liczbę gwoździ, które mogą być na równej wysokości po uderzeniach Kozika. Przykład Dla danych wejściowych: 6 2 2 3 3 3 4 5 poprawnym wynikiem jest: 5 Wyjaśnienie do przykładu: Kozik może uderzyć dwa ostatnie gwóździe o wadze 4. i 5., tak aby pięć gwoździ było na wysokości 3. 23 3.4. DZIEŃ TRZECI ROZDZIAŁ 3. ROZWIĄZANIA Opracowanie: Gwoździe Autor opracowania: Jacek Tomasiewicz Dostępna pamięć: 32 MB Dzień 3, 28.09.2011 Gwoździe Wstęp Załóżmy, że chcemy, aby jak najwięcej gwoździ było wbitych na wysokość x. Możemy wtedy dobić maksymalnie min(k, liczba gwoździ > x). Minimum z tych dwóch wartości, ponieważ dostępny czas Kozika nie pozwala na wbicie większej liczby gwoździ niż k, oraz możemy wbijać tylko gwoździe położone na wysokości większej lub równej x. Tutaj warto zauważyć, że gwoździ położonych na wysokości x nie opłaca się wbijać, gdyż nie zwiększają wyniku, a tylko zużywamy czas Kozika. Zastanówmy się, jak wybierać wartości x, które dalej będziemy nazywać kandydatami. Kandydatami mogą być wszystkie wartości z przedziału [0, 109 ]. Możemy jednak trochę to przyśpieszyć. Załóżmy, że mamy posortowane wartości kolejnych gwoździ 0 6 x1 6 x2 . . . xn 6 109 . Wszystkie wartości tych gwoździ mieszczą się w przedziale [0, 109 ]. Takich kandydatów zostawimy i pokażemy, że innych nie opłaca się rozpatrywać. Jeśli mamy pewne xi 6 xi+1 , to żadnych wartości pomiędzy nimi, czyli xi + 1, xi + 2, . . . , xi+1 − 1 nie sprawdzamy. Zauważmy, że nie opłaca się wbijać gwoździ na wysokość xi + k, gdzie 1 6 k 6 xi+1 − xi − 1, ponieważ gdybyśmy wbili te same gwoździe na wysokość xi , to uzyskalibyśmy wynik większy o liczbę gwoździ na wysokościach xi . Rozwiązanie wolne O(n2 ) W rozwiązaniu wolnym zastosujemy algorytm, robiący dokładnie to, co zostało powyżej opisane. Przejrzymy wszystkie gwoździe, uznając że każdy z nich jest kandydatem i dla każdego oddzielnie obliczymy, ile gwoździ możemy dobić do takiej wysokości. 1 2 3 4 5 6 7 8 9 10 11 12 read ( n , k , t [ ] ) wynik := 0 f or i := 1 to n do kandydat := t [ i ] rowne , w i e k s z e := 0 f or j := 1 to n do i f t [ j ] == kandydat then rowne := rowne + 1 i f t [ j ] > kandydat then w i e k s z e := w i e k s z e + 1 wynik := max( wynik , rowne + min ( k , w i e k s z e ) ) write ( wynik ) Złożoność czasowa takiego rozwiązania wynosi O(n2 ), ponieważ kandydatów jest O(n) i dla każdego z nich przeglądamy wszystkie gwoździe. Za takie rozwiązanie można było uzyskać około 60 punktów. 46 ROZDZIAŁ 3. ROZWIĄZANIA 3.4. DZIEŃ TRZECI Rozwiązanie wzorcowe O(n · log n) Aby jeszcze szybciej rozwiązać zadanie, posortujemy wszystkie gwoździe, dzięki czemu szybko będziemy odpowiadać na pytanie, ile gwoździ jest równych, a ile większych od badanego kandydata. 1 2 3 4 5 6 7 8 9 10 11 12 13 read ( n , k , t [ ] ) posortuj ( t ) i := 1 wynik := 0 while ( i <= n ) do kandydat := t [ i ] rowne := 0 while ( i <= n and t [ i ] == kandydat ) do i := i + 1 rowne := rowne + 1 w i e k s z e := n − i wynik := max( wynik , rowne + min ( k , w i e k s z e ) write ( wynik ) Ponieważ czas posortowania tablicy kosztuje O(n · log n), to złożoność czasowa takiego rozwiązania wynosi O(n · log n). Rozwiązanie alternatywne O(n · log n) Jeśli n 6 k, to wynikiem jest oczywiście n, ponieważ Kozik nie może wbić więcej gwoździ, niż ma dane. Dalej zakładamy, że n > k. Załóżmy, że mamy posortowane gwoździe niemalejąco, czyli x1 6 x2 6 . . . 6 xn . Wybierzmy k najwyższych gwoździ, będą to odpowiednio xn−k+1 6 xn−k+2 6 . . . 6 xn . Ponieważ jest to dokładnie k gwoździ, to możemy je wszystkie wbić na pewną wysokość nie większą od xn−k+1 , w szczególności może to być dowolna z wysokości pozostałych n − k gwoździ. Łatwo zauważyć, że opłaca się wybrać najczęściej powtarzającą się wysokość i do niej zrównać wszystkie wybrane gwoździe. 1 2 3 4 5 6 7 8 9 10 11 read ( n , k , t [ ] ) i f n <= k then write ( n ) else posortuj ( t [ ] ) i l e , m := 1 f or i := 1 to n−k−1 do i f t [ i ] == t [ i +1] then i l e := i l e + 1 e l s e i l e := 1 m := max(m, i l e ) write ( k + m) Złożoność czasowa takiego rozwiązania wynosi O(n · log n). Rozwiązanie to zostało wymyślone przez uczestniczkę obozu – Magdalenę Szarkowską. Postanowiliśmy je opisać ze względu na dużą pomysłowość i prostotę rozwiązania. 47 8.2. DZIEŃ PIERWSZY ROZDZIAŁ 8. ZADANIA Zadanie: Drzewa Autor zadania: Łukasz Jocz Dostępna pamięć: 32 MB Dzień 1, 26.09.2011 Drzewa Pamiętacie Fifusia, który nie znosił informatyki? Obecnie dowódca postawił przed nim bardzo ważne zadanie. Fifuś ma nadzieję, że jeśli uda mu się je wykonać, to wyrwie się z korpusu szeregowych i zostanie mianowany kapralem. Fifuś wraz ze swoim oddziałem jest obecnie na froncie, ukryty w bazie, a na zachód od nich roztacza się niebezpieczny obszar, na którym mogą znajdować się nieprzyjaciele. Na obszarze tym znajduje się n − 1 ponumerowanych drzew (od 2 do n). Baza, która nie jest drzewem (oznaczona numerem 1), położona jest na wschód w stosunku do innych drzew. Od każdego drzewa wychodzi dokładnie jedna ścieżka w kierunku wschodnim, która prowadzi do bazy lub do innego drzewa oraz pewna liczba ścieżek w kierunku zachodnim, które prowadzą do innych drzew. Ponadto z bazy do każdego drzewa da się dojść na dokładnie jeden sposób. Misja Fifusia rozpocznie się przy pewnym drzewie (lub w bazie) i będzie polegała na przemieszczaniu się pomiędzy drzewami w kierunku zachodnim tak długo, jak to będzie możliwe. Każda ścieżka ma określoną trudność, która wyrażana jest za pomocą małych liter alfabetu: a oznacza najłatwiejszą ścieżkę, z najtrudniejszą. Fifuś, jak przystało na dzielnego żołnierza, nie stroni od niebezpieczeństwa. Chciałby, aby misja, którą odbędzie, była najtrudniejszą możliwą. Spośród dwóch misji trudniejsza jest ta, w której trudniejsza jest pierwsza ścieżka, na której te misje się różnią. Jeśli trudności kolejnych ścieżek w obu misjach są odpowiednio takie same, to Fifusia interesuje misja, która kończy się przy drzewie o najmniejszym numerze. Niestety Fifuś nie wie, gdzie będzie musiał zacząć swoją misję, dlatego dla każdego drzewa (i bazy) chciałby znać najtrudniejszą misję rozpoczynającą się w danym miejscu. Twoim zadaniem jest mu pomóc. Musisz się pospieszyć, bo Gogoli jest coraz więcej, a oddział Fifusia jest w potrzasku. Wejście Pierwszy wiersz wejścia zawiera jedną liczbę całkowitą n (1 6 n 6 500 000). W n − 1 następnych wierszach znajdują się opisy ścieżek pomiędzy drzewami. W i–tym wierszu znajduje się liczba całkowita pi (1 6 pi 6 i − 1) oznaczająca drzewo (lub bazę), do którego dojedziemy idąc wschodnią ścieżką od drzewa o numerze i oraz mała litera alfabetu ci oznaczająca trudność tej ścieżki. W testach wartych około 35% punktów zachodzi dodatkowy warunek n 6 10 000, a w testach wartych około 70% punktów zachodzi n 6 100 000. Wyjście Na standardowym wyjściu powinno się pojawić n liczb całkowitych d1 , d2 , . . . , dn , w oddzielnych wierszach, gdzie di oznacza numer drzewa, przy którym kończy się najtrudniej126 ROZDZIAŁ 8. ZADANIA 8.2. DZIEŃ PIERWSZY sza misja rozpoczynająca się przy i–tym drzewie (lub bazie). Jeżeli z wierzchołka i nie wychodzi, żadna krawędź w kierunku zachodnim, to należy wypisać 0. Przykład Dla danych wejściowych: 5 1 1 3 3 a a b a poprawnym wynikiem jest: 4 0 4 0 0 127 9.2. DZIEŃ PIERWSZY ROZDZIAŁ 9. ROZWIĄZANIA Opracowanie: Drzewa Autor opracowania: Ł. Jocz, M. Litwin Dostępna pamięć: 32 MB Dzień 1, 26.09.2011 Drzewa Wstęp Pomijając historię o Fifusiu, naszym zadaniem jest dla każdego wierzchołka w drzewie ukorzenionym znalezienie największej leksykograficznie ścieżki, zaczynającej się w danym wierzchołku i, a kończącej w jego poddrzewie. Niech best[i] będzie wierzchołkiem, w którym kończy się taka ścieżka. Naszym celem jest obliczenie wartości best[i] dla 1 6 i 6 n. Rozwiązanie o złożoności pamięciowej i czasowej O(n log n) Poniższe rozwiązanie przedstawia wartościową technikę rozwiązywania podobnych zadań, jednakże technika ta jest kosztowna pamięciowo. Obserwacja.1. Dla każdego wierzchołka a istnieje taki jego syn b, że albo best[a] = best[b] (gdy b nie jest liściem), albo best[a] = b (gdy b jest liściem). Inaczej mówiąc, największa leksykograficznie ścieżka z wierzchołka i kończy się w tym samym wierzchołku, co największa leksykograficznie ścieżka z pewnego jego syna, lub kończy się w tym synu, jeśli ten syn jest liściem. Zauważmy, że jeśli będziemy potrafili szybko (w złożoności O(log n)) porównać dwie ścieżki na drzewie i określić, która z nich jest większa leksykograficznie, to będziemy potrafili rozwiązać cały problem w złożoności O(n log n). Przechodząc drzewo algorytmem DFS dla każdego wierzchołka u, będziemy przeglądać wszystkich jego synów v i porównywać ścieżki u best[v], gdy v nie jest liściem lub u v, gdy v jest liściem i wybierzemy największą leksykograficznie spośród tych ścieżek. Dla każdego wierzchołka u wykonamy wówczas dokładnie tyle porównań ścieżek, ile wynosi liczba dzieci wierzchołka u, ponieważ, zgodnie z wyżej przedstawioną obserwacją, dla każdego syna wystarczy sprawdzić jedną ścieżkę. Ponieważ suma stopni wierzchołków w drzewie jest rzędu O(n), zatem łącznie w algorytmie wykonamy tyle porównań ścieżek. Pseudokod takiego rozwiązania: 1 2 3 4 5 6 7 8 9 10 11 12 function d f s ( u ) b e s t [ u ] := 0 f or każdego w i e r z c h o ł k a v , k t ó r y j e s t synem w i e r z c h o ł k a u dfs (v) i f ( v = l i ś ć ) then i f ( b e s t [ u ] = 0 ) or ( ś c i e ż k a u −> v j e s t w i ę k s z a l e k s y k o g r a f i c z n i e od ś c i e ż k i od u do b e s t [ u ] ) then b e s t [ u ] := v e l s e ( v != l i ś ć ) i f ( b e s t [ u ] = 0 ) or ( ś c i e ż k a u −> b e s t [ v ] j e s t w i ę k s z a l e k s y k o g r a f i c z n i e od ś c i e ż k i u −> b e s t [ u ] ) then b e s t [ u ] := b e s t [ v ] 150 ROZDZIAŁ 9. ROZWIĄZANIA 9.2. DZIEŃ PIERWSZY Zatem w dalszej części opracowania skupimy się na tym, jak szybko stwierdzić, która z dwóch ścieżek jest większa leksykograficznie. Porównanie dwóch ścieżek Zgodnie z definicją kolejności leksykograficznej większe leksykograficznie jest te słowo, w którym na pierwszej różniącej się pozycji występuje większa litera. Zatem, aby stwierdzić, która z dwóch ścieżek jest większa leksykograficznie, będziemy próbowali znaleźć pierwsze miejsce, gdzie litery na tych ścieżkach się różnią. Wówczas wystarczy, że porównamy te litery i stwierdzimy, która z nich jest większa. Teraz głównym problemem staje się znalezienie pierwszych miejsc na tych ścieżkach, gdzie te ścieżki się różnią. Spróbujemy to zrobić za pomocą wyszukiwania binarnego. Aby to uczynić, na początku dla każdego wierzchołka wyznaczmy jego przodków w odległościach 20 , 21 , . . . , 2log n . Możemy to zrobić dynamicznie w następujący sposób. Niech przodek[u][i] oznacza przodka wierzchołka u, odległego o 2i krawędzi. Przodkiem w odległości 20 = 1 jest po prostu ojciec wierzchołka, czyli przodek[u][0] = ojciec[u]. Natomiast, aby policzyć przodka wierzchołka u w odległości 2i , wystarczy znać dla każdego wierzchołka jego przodka w odległości 2i−1 . Wówczas wystarczy wykonać z wierzchołka i dwa skoki – każdy na odległość 2i−1 . Zatem przodkiem oddalonym od wierzchołka u o 2i−1 jest wierzchołek przodek[u][i − 1]. Natomiast znamy też wierzchołek oddalony o 2i−1 od wierzchołka przodek[u][i − 1] i jest nim przodek[przodek[u][i − 1]][i − 1]. Zatem wierzchołek przodek[przodek[u][i − 1]][i − 1] jest oddalony od wierzchołka u dokładnie o 2 ∗ 2i−1 = 2i . Obliczanie przodków możemy przedstawić w pseudokodzie następująco: 1 2 3 4 5 f or u := 1 to n do przodek [ u ] [ 0 ] = o j c i e c [ u ] f or i := 1 to l o g ( n ) do f or u := 1 to n do przodek [ u ] [ i ] := przodek [ przodek [ u ] [ i − 1 ] ] [ i −1] Złożoność tego fragmentu to O(n log n). Podczas wyszukiwania binarnego będziemy musieli umieć stwierdzić, czy dwie ścieżki są sobie równe. Najprościej to zrobić używając hashowania – hashując ścieżkę od korzenia do każdego wierzchołka. Ponieważ w wyniku operacji na hashach wyniki mogą być bardzo duże, będziemy trzymać jedynie ich wartość modulo pewna stała. W tym akapicie wszystkie obliczenia wykonywane są modulo, jednak pominiemy to dla uproszczenia zapisu. Hash ścieżki od 1 do u możemy obliczyć następująco: hash[u] = base ∗ hash[ojciec[u]] + c[u ojciec[u]], gdzie c[u ojciec[u]] jest literą na krawędzi od wierzchołka u do jego ojca, a base jest liczbą będącą podstawą hashowania. Aby wyznaczyć hash ścieżki od u do v wystarczy wziąć hash ścieżki od 1 do v i odjąć hash ścieżki od 1 do u pomnożony przez stałą base podniesioną do odpowiedniej potęgi – hash[u v] = hash[v] − base[deep[v]−deep[u]] ∗ hash[u], gdzie deep[i] jest głębokością wierzchołka i w drzewie. Aby nie musieć za każdym razem obliczać potęg liczby base, możemy je wszystkie wcześniej spamiętać wykonując preprocessing. Teraz powróćmy do głównej części naszego zadania, czyli do stwierdzenia, która ze ścieżek a b, czy a c jest większa leksykograficznie. Dla uproszczenia przyjmijmy, że deep[b] > deep[c], czyli wierzchołek b leży niżej w drzewie. Gdy tak nie jest, problem jest analogiczny. Na początku będziemy chcieli znaleźć przodka wierzchołka b, który jest na 151 9.2. DZIEŃ PIERWSZY ROZDZIAŁ 9. ROZWIĄZANIA tej samej głębokości co wierzchołek c. W tym celu będziemy próbować skakać o kolejne potęgi dwójki od log n do 1 i sprawdzać czy po wykonaniu skoku znaleźlibyśmy się wyżej w drzewie, niż wierzchołek c, czy też nie. Jeśli po wykonaniu skoku znaleźlibyśmy się wciąż niżej niż wierzchołek c, to ten skok wykonujemy, ponieważ nie chcemy przeskoczyć wierzchołka c, a jedynie zrównać się do jego głębokości. Zobaczmy pseudokod: 1 2 3 4 d := b f or i := log n to 0 do i f przodek [ d ] [ i ] != 0 and deep [ przodek [ d ] [ i ] ] >= deep [ c ] then d := przodek [ d ] [ i ] Po wykonaniu tego fragmentu kodu d jest przodkiem b, który jest na tej samej wysokości co wierzchołek c. Jest tak dlatego, że zawsze skaczemy o największą potęgę dwójki, jaka się zmieści. Można to tłumaczyć w ten sposób, że gdy przedstawimy różnicę głębokości tj. deep[b] − deep[c] w systemie dwójkowym, to skoki które wykonamy, będą odpowiadały zapalanym bitom w tej liczbie. Teraz w podobny sposób spróbujemy znaleźć pierwsze miejsce, gdzie ścieżki a d oraz a c się różnią. Będziemy próbować skakać od wierzchołków d i c do góry o kolejne potęgi dwójki, otrzymując wierzchołki d0 i c0 , i sprawdzać czy ścieżki a d0 oraz a c0 są takie same. Jeżeli są takie same, to nie wykonujemy skoku, gdyż oznacza to, że jest on zbyt duży. W przeciwnym wypadku wykonujemy skoki podobnie jak przy wyznaczaniu wierzchołka d. Pseudokod mógłby wyglądać następująco: 1 2 3 4 5 6 7 d0 := c 0 := f or i if d c := log n to 0 do ( deep [ a ] < deep [ przodek [ d0 ] [ i ] ] ) and ( hash [ a−>przodek [ d0 ] [ i ] ] != hash [ a−>przodek [ c 0 ] [ i ] ] ) then d0 := przodek [ d0 ] [ i ] c 0 := przodek [ c 0 ] [ i ] Znalezione wierzchołki d0 i c0 są pierwszymi miejscami, gdzie ścieżki a dia c się różnią. Wystarczy teraz porównać krawędzie wychodzące z tych wierzchołków do góry, aby stwierdzić, która ścieżka jest większa leksykograficznie. Może się też zdarzyć tak, że ścieżki a d oraz a c są w całości takie same. Wtedy nie znajdziemy takiego miejsca, gdzie te ścieżki się różnią. Jednakże pamiętajmy, że ścieżka a d jest skróconą ścieżką a b. Zatem jeżeli b 6= d to ścieżka a b jest dłuższa od ścieżki a c, a zatem jest większa leksykograficznie. W przeciwnym razie ścieżki a bia c są równe, a zatem interesuje nas ta, w której numer wierzchołka końcowego jest mniejszy. Rozwiązanie wzorcowe O(n) Niech gdzie[i] będzie następnym (po i) wierzchołkiem na największej leksykograficznej ścieżce z wierzchołka i. Rozwiązanie polega na wyliczeniu wartości best[i] oraz gdzie[i] dla wszystkich wierzchołków drzewa. Na początku ustalmy dla liści drzewa wartość gdzie[i] na 0. Będziemy wyliczać wartości dla wierzchołka i, po wcześniejszym wyliczeniu wartości best[] i gdzie[] dla jego synów. Iterując po kolejnych synach wierzchołka i, porównujemy, czy ścieżka idąca przez 152 ROZDZIAŁ 9. ROZWIĄZANIA 9.2. DZIEŃ PIERWSZY ten wierzchołek jest większa leksykograficznie od największej aktualnie znalezionej. Do porównania ścieżek wykorzystujemy wyliczone wartości tablicy gdzie[]. 1 2 3 4 5 6 7 8 9 10 11 { znak [ ] <− l i t e r k a na k r a w ę d z i do o j c a } { f u n k c j a porównuje c z y ś c i e ż k a z x j e s t w i ę k s z a od ś c i e ż k i z y } function porownaj ( x , y ) while g d z i e [ x ] and g d z i e [ y ] and znak [ g d z i e [ x ] ] == znak [ g d z i e [ y ] ] x := g d z i e [ x ] y := g d z i e [ y ] i f g d z i e [ x ] and g d z i e [ y ] then r e t u r n ( znak [ g d z i e [ x ] ] > znak [ g d z i e [ y ] ] ) i f ( not g d z i e [ x ] ) and ( not g d z i e [ y ] ) then return (x < y) r e t u r n ( g d z i e [ x ] != 0 ) Zauważmy, że funkcja porównująca wykona co najwyżej tyle iteracji, co długość krótszej ścieżki – obserwacja ta jest kluczowa, aby uzasadnić złożoność rozwiązania. Rozważmy najbardziej pesymistyczny przypadek, czyli gdy wszystkie krawędzie mają ten sam znak. Wtedy największe leksykograficznie ścieżki są najdłuższymi ścieżkami. • s(t) to najdłuższa ścieżka w drzewie t, • f (s(t)) to liczba operacji porównywania wykonanych, aby obliczyć wartości best[] i gdzie[] dla wierzchołków znajdujących się na s(t), • trees(s(t)) to zbiór poddrzew drzewa t, które są rozłączne z s(t) oraz których korzeń jest bezpośrednio połączony z s(t). Zauważmy, że obliczając wartości best[] i gdzie[] dla wierzchołków z s(t), porównujemy ze sobą ścieżki, z których krótsza jest równa s(t0 ), gdzie t0 ∈ trees(s(t)). P Zatem f (s(t)) ≈ t0 ∈trees(s(t)) length(s(t0 )). Niech T (t) to złożoność czasowa wyliczenia wartości best[] i gdzie[] P dla drzewa t. P P Wtedy T (t) = f (s(t))+ t0 ∈trees(s(t)) T (t0 ) = t0 ∈trees(s(t)) O(s(t0 ))+ t0 ∈trees(s(t)) T (t0 ). Rozwijając rekurencję otrzymujemy, że T (t) = O(n). 153