Informatyczny kącik olimpijski
Or
Tym razem omówimy zadanie Or, które pojawiło się w 2018 roku na Junior Balkan Olympiad in Informatics w Timisoarze (Rumunia).
Zadanie. Dana jest liczba całkowita oraz kwadratowa macierz
rozmiaru
W każdym polu macierzy znajduje się jedna liczba całkowita. Z ilu pól składa się najmniejsza prostokątna podmacierz macierzy
której
bitowy wszystkich elementów wynosi
Dla uproszczenia, wartością podmacierzy będziemy nazywali wartość równą 'owi wszystkich liczb w tej podmacierzy.
Rozwiązanie
Zaczniemy od najbardziej intuicyjnego pomysłu. Rozwiązanie polega na niezależnym sprawdzeniu każdej podmacierzy i wybraniu tej, która ma wartość oraz jest najmniejsza. Wszystkich podmacierzy jest
(lewy górny róg możemy wybrać na
sposobów, podobnie prawy dolny róg możemy wybrać na
sposobów). Naiwne obliczenie wartości podmacierzy (iterowanie po wszystkich elementach) działa w czasie
Zatem całe rozwiązanie działa w czasie
Szybkie obliczanie wartości podmacierzy
Skonstruujemy strukturę danych, która będzie umożliwiała obliczanie wartości dowolnej podmacierzy.
W naiwnym rozwiązaniu iterujemy po każdym polu podmacierzy. Oczywiście takie rozwiązanie jest wolne, dlatego je przyspieszymy. Chcemy, w pewnym sensie, niektóre pola zliczać hurtowo. Zatem obliczymy wartość wszystkich podmacierzy o rozmiarze gdzie
są liczbami postaci
dla
Zauważmy, że takich podmacierzy w całej macierzy
będzie
ponieważ w każdym polu jest zaczepionych
podmacierzy

Wartości wyżej opisanych podmacierzy będziemy obliczali od tych, które mają najmniejszą liczbę pól, do tych, które mają największą liczbę pól. Wartość podmacierzy o wymiarach to liczba zapisana w tym polu. Wartość podmacierzy o wymiarach
to
wartości dwóch mniejszych podmacierzy o wymiarach
jeśli
lub
wartości dwóch mniejszych podmacierzy o wymiarach
w przeciwnym przypadku. Przykładowo: wartością podmacierzy o wymiarach
jest
wartości dwóch mniejszych podmacierzy o wymiarach
każda.
Konstrukcja struktury zajmuje pamięci i odbywa się w czasie
Pozostało nam jeszcze opisanie, w jaki sposób znaleźć wartość dowolnej podmacierzy. Nazwijmy ją i niech ma wymiary
Jej wartość obliczymy na podstawie znanych wartości innych podmacierzy. Ustalmy takie największe
i największe
że
oraz
Weźmy takie cztery podmacierze
o wymiarach
że każde pole
będzie należało do przynajmniej jednej z tych czterech podmacierzy. Wówczas wartością
będzie
wartości tych czterech podmacierzy.

Przykład: chcemy obliczyć wartość podmacierzy, której lewe górne pole to a prawe dolne to
Zauważmy, że tę podmacierz możemy pokryć czterema podmacierzami o wymiarach
dla których wyniki znamy. Zatem wartością tej podmacierzy jest
wartości czterech mniejszych podmacierzy.
Rozwiązanie
Zauważmy, że dzięki powyższej strukturze danych potrafimy w czasie obliczyć wartość dowolnej podmacierzy. Zatem w naturalny sposób możemy przyspieszyć rozwiązanie z
do
Wystarczy przejrzeć wszystkie
podmacierzy macierzy
i spośród tych o wartości
wybrać najmniejszą.
Rozwiązanie
W tym rozwiązaniu iterujemy po każdym przedziale wierszy. W ustalonym przedziale wierszy szukamy najmniejszej podmacierzy o wartości i wysokości równej liczbie wierszy w tym przedziale. Od teraz możemy o tym myśleć jak o problemie jednowymiarowym, ponieważ wysokość jest ustalona. Szukamy najkrótszego fragmentu, który będzie miał wartość
Ten problem możemy rozwiązać za pomocą techniki o nazwie "gąsienica". Na początku ustawiamy dwa wskaźniki (początek i koniec gąsienicy) w pierwszej kolumnie. Następnie symulujemy ruch gąsienicy. Jeśli aktualna wartość jest mniejsza od
i może jeszcze osiągnąć
wtedy rozszerzamy gąsienicę o kolejną kolumnę. W przeciwnym przypadku skracamy gąsienicę. W każdym stanie, za pomocą powyżej opisanej struktury, w czasie
obliczamy wartość aktualnie rozpatrywanej podmacierzy. Dla każdego rozpatrywanego przedziału wierszy gąsienica wykona liniowo wiele ruchów. Wszystkich przedziałów wierszy do rozpatrzenia jest
zatem całe rozwiązanie działa w czasie