Zadanie

Na obdĺžnikovom ostrove síce nebývajú povodne veľmi často, ale keď prídu, je to úplná katastrofa. Zaplavené sú lesy, lúky, námestia, domy a paneláky do výšky prvého poschodia. Takisto všade pláva množstvo odpadkov a opustených domácich zvieratiek. Obdĺžnikový ostrov sa totiž nachádza v strede obdĺžnikového jazera do ktorého vteká nie-až-tak-obdĺžniková rieka, ktorá pramení vo vzdialených trojuholníkových horách.

Pred rokom a pol sa preto začalo s výstavbou protipovodňových ochranných múrov. Väčšina obyvateľov sa aktívne zapájala a občas postavli štvorcový kúsok múru.1

Ľudia si väčšinou stavajú múry vo svojom okolí, no niektorí podnikaví jedinci ich stavajú aj tam, kde ich netreba – napríklad v oblastiach, ktoré sú už celé obohnané múrom – alebo tam, kde sú absolútne zbytočné – napríklad osamotený metrový kus múru v strede poľa.

Takéto aktivity im už nebudú preplatené.

Vďaka novele zákona o preplácaní protipovodňových múrov budú odteraz preplácané len múry, ktoré skutočne niečo ochránia. Novela zákona síce platiť bude, ale ako zistiť, či sú múry zbytočné? Ministerstvo vám teda dalo zákazku: Chcú o každom kúsku múru zistiť, aký prospešný bol pre spoločnosť, teda aké veľké územie bude chránené po jeho postavení.

Úloha

Ostrov si môžeme predstaviť ako obdĺžnik rozdelený na \(w \times h\) štvorčekov. Každý štvorček môže byť buď prázdny, alebo na ňom môže byť postavená časť protipovodňovej ochrany.

Voda dokáže tiecť ôsmimi smermi a priteká na každé políčko na okrajoch ostrova. Samozrejme, voda nevie zaplaviť políčko, na ktorom je postavená protipovodňová ochrana.

Dostanete rozmery ostrova a pozície, kde sa postupne stavajú múry. Na začiatku je ostrov prázdny. Vašou úlohou je po postavení každého kúsku múra povedať, aká plocha je chránená pred vodou.

Táto úloha sa líši od Ochrany pred povodňami tým, že je online, teda skutočne potrebujete odpovedať hneď po postavení múra.

Formát vstupu

Na prvom riadku vstupu dostanete dve celé čísla \(w\) a \(h\) (\(1 \leq w,h \leq 2\,000\)), pričom \(w\) je šírka a \(h\) výška obdĺžnikového ostrova.

Na druhom riadku je číslo \(n\) (\(1 \leq n \leq w \times h\)) – počet štvorcových kúskov protipovodňového múru, ktoré budú postavené.

Každý z nasledujúcich \(n\) riadkov obsahuje dve čísla \(a_i\) a \(b_i\), ktoré sa zmestia do 32-bitovej premennej. Súradnice pozície \(x_i, y_i\) (\(1 \leq x_i \leq w\), \(1 \leq y_i \leq h\)), kde bude postavený \(i\)-ty kúsok múra vypočítate nasledovne: Nech \(v\) je posledný vypísaný výsledok. Na začiatku nastavme \(v=0\). Potom \(x_i = a_i ~\mathrm{xor}~ v, y_i = b_i ~\mathrm{xor}~ v\), teda pozíciu získate z \(a_i, b_i\) zoxorovaním s predošlým výsledkom, pričom používame bitový xor (bitwise xor), v C++ ^.

Formát výstupu

Vypíšte \(n\) takých riadkov, že v \(i\)-tom riadku bude jedno celé číslo – plocha územia, ktoré je chránená protipovodňovým múrom po postavení \(i\)-teho kúsku. To znamená počet takých políčok, na ktoré nevie pritiecť voda.

Príklad

Input:

4 4
10
1 1
0 3
3 1
1 2
6 7
6 4
5 4
4 4
11 11
10 13

Output:

1
2
3
4
5
6
7
9
9
10

Prvých 8 kúskov múra ochráni pred povodňami územie veľkosti \(3 \times 3\). Deviaty štvorček nemá vôbec žiadny účinok, lebo políčko \((2,2)\) už bolo chránené. Desiaty kúsok neuzavrie žiadne územie a teda prispeje len svojou plochou.


  1. Ministerstvo vodohospodárstva preplácalo náklady na výstavbu.

V tejto úlohe nám pomôže to, čo ste viacerí skúšali už pri riešení pôvodnej KSP úlohy Ochrana pred povodňami – prehľadávanie, pričom sa pomocou union-findu snažíme detekovať, kedy sme uzavreli nejaké väčšie územie a kedy nie. Pri stavaní väčšiny múrov sa totiž zväčší chránená plocha len o 1, prípadne o 0, ak ho postavíme v už chránenom území.

Predstavme si, že kúsky múra sú vrcholy grafu spojené hranami s okolitými najviac 4 kúskami múra. Môžeme si pamätať súvislé komponenty múrov a vieme, že nejakú väčšiu plochu ochránime len vtedy, keď okolo nej uzavrieme múr – keď spojíme jeden múrový komponent sám so sebou. Zisťovanie, v akom súvislom komponente je políčko, a spájanie dvoch komponentov v čase (dokonca menšom ako) \(O(\log n)\) vieme implementovať štruktúrou union-find.

Keď uzavrieme oblasť, stačí nám spustiť prehľadávanie z políčka, na ktoré sme práve pridali múr. Toto prehľadávanie musí zistiť, ktorými smermi sa z tohto políčka dá dostať na kraj (teda sú vonku/nechránené) a ktrorými smermi zostaneme vovnútri chránenej oblasti. Následne stačí označiť vnútro oblasti ako ochránené. Ako ale zistiť, čo je vonku a čo vnútri?

Pridaním ľubovoľného kúska múru vieme rozdeliť plochu na 1-4 územia. To, na koľko území plochu rozdelíme však vieme zistiť len z údajov o tom, v ktorých komponentoch súvislosti sú múry na susedných 8 políčkach.

. . .  2 2 2  . 1 .  . 1 .
1 X 1  . X .  3 X 4  1 X 1
. . .  1 1 1  . 2 .  . 1 .

Vo vyššie uvedených príkladoch reprezentuje . prázdne políčko a 1-4 políčka, na ktorých sú múry, pričom tieto múry patria do komponentov 1-4. Pridaním múra na políčko X rozdelíme plochu na 2, 1 (teda nič nerozelíme), 1 a 4 územia. Zistiť počet rôznych území (a pre každé územie prázdne políčka, ktoré sú jeho súčasťou) vám prenechávame ako implementačnú výzvu. Neodporúčame hardcodovať všetky možnosti.

Vieme teda, na koľko území je rozdelené okolie políčka X. Niektoré z území budú vnútorné a niektoré vonkajšie. Pokiaľ sme múr nepostavili v už ochránenej ploche, vdžy bude aspoň jedno územie vonkajšie (dokážte!). Pokiaľ všetku vodu okolo ostrova pokladáme za jednu oblasť, vždy bude dokonca práve jedno z oddelených území vonkajšie (dokážte!) a 0-3 vnútorné – ochránené.

Ak by sme pustili prehľadávania postupne do všetkých plôch, mohlo by sa nám stať, že na vodu narazíme, až keď prehľadáme väčšinu mapy. Ak by sme ale pustili prehľadávania paralelne …

Nech plochu rozdelíme na 2 územia. Pustíme 2 prehľadávania, do každého územia jedno. Prehľadávať budeme tak, že vždy preskúmame jedno políčko v jednom území a jedno v druhom. V každom čase budeme mať teda prehľadané rovnako veľké časti oboch území. Zastaneme, keď narazíme na vodu – vtedy stačí prehľadať druhé územie, alebo keď vyplníme nejakú celú oblasť – vtedy už nemusíme prehľadávať druhé územie, lebo vieme, že je vonkajšie.

Ak sme postavením múra ochránili oblasť veľkosti \(s\), prehľadáme tak najviac \(2s\) políčok. Úvahy sa dajú zovšeobecniť aj pre prípady, keď rozdelíme plochu na viac oblastí (spúšťame najviac 4 paralelné prehľadávania do najviac 4 území a každé prehľadávanie zastavíme, ak sme v ňom narazili na vodu alebo ak sme už vyplnili všetky ostatné územia). Rozmyslite si, že ak pridaním múra plochu rozdelíme iba na \(1\) oblasť, tak si nemôžeme dovoliť púšťať prehľadávanie. To ale nevadí, nakoľko táto jediná oblasť musí byť vonkajšia.

Každé políčko označíme najviac raz ako ochránené – počas nejakého prehľadávania. Celkovo teda prehľadáme najviac \(2 \cdot w \cdot h\) políčok. Naše online riešenie má teda celkovú časovú zložitosť \(O(w \cdot h + q)\).

Diskusia

Tu môžte voľne diskutovať o riešení, deliť sa o svoje kusy kódu a podobne.

Pre pridávanie komentárov sa musíš prihlásiť.