Informatyczny kącik olimpijski
XORanges
W tym odcinku omówimy rozwiązanie zadania XORanges, które pojawiło się na trzecich zawodach European Junior Olympiad in Informatics (Maribor, Słowenia).
Zadanie (XORanges). Dany jest ciąg liczb naturalnych
oraz
poleceń dwóch typów. 1) Zmień wartość
-tego elementu. 2) Podaj współczynnik przedziału
Współczynnik przedziału
obliczamy w następujący sposób: dla każdego podsłowa (spójnego fragmentu) tego przedziału liczymy xor jego wartości, następnie xorujemy te wyniki, otrzymując współczynnik przedziału. Przykładowo współczynnik przedziału
wynosi
Zaproponuj algorytm, który jest w stanie możliwie szybko wykonać wszystkie polecenia podane na wejściu.
Na początku przyjmijmy, że polecenia typu będziemy wykonywali w czasie
poprzez zmianę wartości
Zatem zajmijmy się odpowiedziami na polecenia typu
Załóżmy, że chcemy obliczyć współczynnik
Na potrzeby artykułu wprowadźmy kilka oznaczeń. Niech:
oznacza ciąg
- "xor podsłowa
" oznacza wartość
Rozwiązanie
Pierwsze rozwiązanie polega na obliczeniu xora każdego z podsłów, gdzie
i oznacza długość przedziału
Obliczenie xora podsłowa odbywa się za pomocą metody naiwnej, polegającej na przejściu po wszystkich elementach. Na koniec xorujemy powyższe wyniki. Rozwiązanie dla jednego polecenia działa w czasie
zatem całkowita złożoność to
Rozwiązanie
W tym rozwiązaniu, podobnie jak wyżej, obliczymy xor podsłów (dla wszystkich
) niezależnie. Jednak tym razem, zamiast naiwnej metody, skorzystamy z obserwacji, że:

gdzie Ciąg
ma analogiczną konstrukcję do ciągu sum prefiksowych i możemy go wygenerować w czasie
Otóż
zaś
(dla
). W ten sposób otrzymaliśmy rozwiązanie działające w czasie
Rozwiązanie
Przypomnijmy proste fakty:
(dla
naturalnego),
(dla
naturalnego),
jest operacją łączną i przemienną.
Na podstawie powyższych faktów możemy zauważyć, że do obliczenia współczynnika przedziału wystarczy znać parzystość liczby wystąpień każdego elementu w wyrażeniu je opisującym. Przykładowo:

gdyż i
występują nieparzyście wiele razy w całym wyrażeniu, zaś
występuje parzyście wiele razy.
Zastanówmy się, ile razy (dla
) występuje we wzorze opisującym współczynnik przedziału
Innymi słowy chcemy obliczyć, w ilu podsłowach występuje
Niech
oznacza tę wartość. Otóż początkiem takiego podsłowa może być element o numerze z przedziału
końcem zaś element o numerze z przedziału

Zatem Współczynnik przedziału to xor zbioru
i
jest nieparzyste
Wyznaczenie tego zbioru realizujemy w czasie
Zatem całe rozwiązanie działa w czasie
Rozwiązanie
Przed nami rozwiązanie wzorcowe. Polecenie będziemy wykonywali nieco inaczej niż poprzednio, ale najpierw opiszemy operację
Przeanalizujmy parzystości elementów ciągu Otóż
jest nieparzyste, jeśli
i
są nieparzyste. Stąd
jest nieparzyste wtedy i tylko wtedy, gdy
są tej samej parzystości. Zatem jeśli
i
są różnej parzystości, to odpowiedzią jest
W przeciwnym przypadku odpowiedzią jest:

Chcemy szybko znajdować wartość powyższego wyrażenia. Zauważmy, że jest to xor elementów na pozycjach parzystych lub nieparzystych ciągu Niech zatem:
Wówczas dla parzystego odpowiedzią jest
zaś dla
nieparzystego odpowiedzią jest
Zbudujmy dwa drzewa przedziałowe. Liśćmi pierwszego z nich niech będą wartości ciągu zaś liśćmi drugiego niech będą wartości ciągu
Pozostałe węzły będą przechowywały xor wartości dzieci. Taka struktura pozwala w czasie
znajdować
przedziału oraz w tym samym czasie obsługiwać operację zmiany wartości elementu (polecenie typu pierwszego). Zatem całe rozwiązanie działa w czasie