BOI 2016
CEOI 2017
BOI 2018
BOI 2019
BOI 2020
CEOI 2020
Fajny płot
Mamy dane prostokątów (),
-ty z nich o szerokości oraz wysokości
().
Ułożone są jeden obok drugiego,
stykają się brzegami oraz wszystkie stykają osi OX.
Należy powiedzieć ile jest podprostokątów o całkowitych współrzędnych,
które w całości zawierają się wśród sumy prostokątów z wejścia,
modulo .
Podzadanie 4
Gdy wszystkie są równe, na wejściu jest tak naprawdę jeden długi prostokąt.
Liczba podprostokątów w prostokącie o wysokości oraz szerokości
wynosi ,
ponieważ niezależnie można wybrać przedział współrzędnych oraz ,
z których będzie się składał prostokąt.
Można to obliczyć w czasie .
Podzadanie 5
W tym podzadaniu zachodzi .
Niech .
Odpowiedzią jest ,
gdzie .
Wynika to z tego, że w -tym kroku są wliczane prostokąty,
których lewy górny róg ma współrzędną
z przedziału .
Podzadanie 6
Dla można dla każdych
policzyć liczbę podprostokątów,
których lewy brzeg znajduje się w -tym prostokącie,
a prawy w -tym.
Dla liczba ta wynosi
,
gdzie jest minimalną wysokością na przedziale ,
a jest sumą szerokości na tym przedziale.
Wynika to z prostego zastosowania zasady włączeń i wyłączeń po tym,
gdzie znajdują się brzegi podprostokąta.
Daje to rozwiązanie w złożoności .
Podzadanie 7 -- rozwiązanie od góry do dołu (find-union)
Będziemy zamiatać prostokąty od góry do dołu,
czyli w kolejności nierosnących .
W momencie, gdy dany prostokąt zostanie już rozpatrzony,
to za pomocą struktury dla zbiorów rozłącznych (find-union) zostanie on złączony
z sąsiednimi prostokątami, które zostały już zamiecione
(można to interpretować jako obniżanie zamiecionych prostokątów
do poziomu miotły i rozpatrywanie ich razem).
Przy czym poza informacją o złączonych prostokątach
trzeba utrzymywać ich sumę długości.
W momencie, gdy prostokąt staje się zamieciony,
za pomocą utrzymanych struktur danych można policzyć
liczbę prostokątów dotykających tego prostokąta
i być może tylko inne, już zamiecione prostokąty.
Daje to niezmiennik, że po zamieceniu prostokąta,
policzony wynik to liczba podprostokątów
wśród zamiecionych prostokątów.
Daje to rozwiązanie w złożoności
przez posortowanie liczb
(czynnik algorytmu Find-Union nie został wliczony do złożoności,
ponieważ jest mniejszy).
Podzadanie 7 -- rozwiązanie od lewej do prawej (stos)
Gdy rozpatrujemy jakiś prawy dolny róg podprostokąta,
zbiór wszystkich możliwych poprawnych lewych górnych rogów
jest sumą pewnych rozłącznych, stykających się prostokątów o rosnących wysokościach.
Podsuwa to pomysł, aby utrzymywać stos takich prostokątów
po rozpatrzeniu prostokątów z wejścia od do .
Żeby pomysł zadziałał, należy wynik dla zdefiniować
jako liczbę podprostokątów przechodzących wśród
prostokątów , ale nie przechodzących przez
prostokąty znajdujące się na stosie.
Aby na końcu otrzymać wynik dla całego zadania,
wystarczy zasymulować jeszcze dodawanie prostokąta
o rozmiarach ,
aby pozbyć się prostokątów na stosie.
W momencie, gdy mamy stos dla
i rozpatrujemy dodawanie -tego prostokąta z wejścia,
będziemy potencjalnie ze stosu zdejmować prostokąty
i dodawać odpowiednią liczbę do wyniku.
Niech będzie rozmiarem prostokąta na wierzchu stosu.
- Jeżeli ,
to wystarczy przedłużyć szerokość prostokąta
na wierzchu stosu o .
- Jeżeli ,
to wystarczy wrzucić prostokąt
na wierzch stosu.
- Jeżeli ,
to trzeba zrzucić pewną ilość prostokątów z wierzchu stosu
aż do momentu, gdy będzie większe równe
wysokości prostokąta na wierzchu stosu.
Przy każdym zrzucaniu akumulujmy długości zrzuconych prostokątów
i rozwiązaniem analogicznym do \textit{podzadania 5}
zliczamy wkład do wyniku nowych prostokątów nie znajdujących się już na stosie.
Daje to rozwiązanie w zamortyzowanej złożoności ,
ponieważ zostanie wykonanych co najwyżej operacji wrzucenia
prostokąta na stos.
O nieco ogólniejszej metodzie rozwiązania tego zadania można przeczytać w artykule
Zliczamy puste prostokąty
z miesięcznika Delta.