Zadanie

Po desiatkach rokov a nespočetných nociach strávených v observatóriu sa mu to konečne podarilo! Bc. et Mgr. et Mudr. et PhDr Peťo Phd. Etc. Csc. konečne objavil planétku. Rozhodol sa ju nazvať KSP-8. A teraz zostáva už len jediné – postaviť raketu a prežiť zvyšok svojho života na vysnívanej planéte. Ale ako na to? Potreboval by poradiť od niekoho, kto má veľa skúseností s lietaním…

Taylor Swift je znova po mnohých rokoch na turné! Swifties vískajú, hateri hateujú a lístky sa míňajú. S novým turné však prichádza aj ďalšia novinka - každý, kto si zakúpi VIP lístok, získa osobne od Taylor radu do života.

Nie všetky Taylorine rady sú však rovnocenné. Napríklad dostať rovnakú radu dvakrát je samozrejme zbytočné. Ktoré lístky si má Peťo kúpiť, aby uspel na svojej misii?

Úloha

Taylor Swift má naplánovaných \(n\) koncertov. Každý z nich je popísaný dvoma číslami \(a_i, b_i; a_i \leq b_i\). Na každom koncerte, ktorého sa Peťo zúčastní dostane Taylorinu radu - ľubovoľné číslo od \(a_i\) do \(b_i\) vrátane. Kvalita jeho rakety potom bude rovná bitovému OR-u všetkých rád, ktoré získal.

Postupne dostávate \(q\) queries. Queries majú 2 typy:

  • Zmenili sa parametre jedného koncertu.
  • Aká je maximálna možná kvalita rakety pri navštívení koncertov \(l\)\(r\) vrátane?

Formát vstupu

V prvom riadku vstupu je číslo \(n\) (\(1 \leq n \leq 3 \cdot 10^5\)) udávajúce počet koncertov, ktoré Taylor plánuje.

Na každom z nasledujúcich \(n\) riadkov sa nachádzajú čísla \(a_i\) a \(b_i\) (\(0 \leq a_i \leq b_i \leq 10^9\)) popisujúce i-ty koncert.

Na ďaľšom riadku sa nachádza číslo \(q\) (\(1 \leq q \leq 3 \cdot 10^5\)) – počet queries.

Každý zo zvyšných \(q\) riadkov popisuje jednu query:

  • u {i} {a} {b} (\(1 \leq i \leq n\)) – Parametre i-teho koncertu sa zmenili na \(a,b\).
  • q {l} {r} (\(1 \leq l \leq r \leq n\)) – Aká je maximálna možná kvalita rakety pri navštívení koncertov \(l\)\(r\) vrátane?

Hodnotenie

Úloha má 4 sady vstupov. V prvých troch platia navyše obmedzenia:

  • V prvej sade platí \(n, q \leq 5000\).
  • V druhej sade sú všetky query typu q – teda nie sú tu žiadne updaty.
  • V tretej sade pre každé \(i\) platí \(a_i == 0\), a to aj po updateoch.

Formát výstupu

Na každú query typu q odpovedajte vypísaním jediného čísla na samostatný riadok - maximálnou možnou kvalitou rakety.

Príklad

Input:

3
1 2
0 1
3 5
4
q 1 2
q 2 3
u 2 0 2
q 2 3

Output:

3
5
7

Pri prvej query zoberieme na prvom koncerte radu \(2\) a na druhom \(1\), a \(2 \operatorname{OR} 1 = 3\). Pri druhej zoberieme \(5\) a \(1\). V prípade poslednej query už vieme na druhom koncerte zobrať aj dvojku, teda dostávame \(2 \operatorname{OR} 5 = 7\).

Tretia podúloha

Pozrime sa najprv na tretiu podúlohu – teda verziu úlohy, kde \(a_i\) je vždy \(0\). Simulujme si jednu q query a pozerajme sa na najvyšší bit výsledku. Ak tento bit nie je nastavený v žiadnom \(b_i\) v intervale, určite to musí byť \(0\). Ak je zapnutý v jednom \(b_i\), určite to chceme takto ponechať, inak by sme si výsledok určite zhoršili. Ten najzaujímavejší prípad ale nastáva, ak je zapnutý vo viacerých. Tu totiž môžeme pre jedno vybrať samotné \(b_i\) a pre druhé také číslo, ktoré má tento bit vypnutý, ale všetky nižšie zapnuté.

Teda napríklad keď v našom intervale nájdeme \(b_1 = 10 = 1010_2\) a \(b_2 = 9 = 1001_2\), tak si pre prvú pozíciu môžeme vybrať samotné \(b_1 = 1010_2\) a pre druhú \(0111_2\). Ich OR potom bude \(1111_2\), čo je evidentne optimálne.

Teda už máme nejaké riešenie tretej podúlohy – pre každú q query si postupne prechádzame bitmi odpovede od najvyššieho, nastavujeme ich podľa toho, či niekde existuje príslušný bit v \(b_i\) a keď také dokonca existujú viaceré, tak zvyšok bitov doplníme jednotkami. u query vyriešime triviálne – proste si prepíšeme dané \(b_i\).

Toto riešenie má ale časovú zložitosť \(O(q n \log A)\), kde \(A\) je najväčšie číslo v poli \(b_i\). Toto je ale príliš pomalé na vyriešenie tretej sady.

Zrýchlenie riešenia

Môžeme si všimnúť dve možné miesta na optimalizáciu – zahodiť zo zložitosti logaritmus alebo dokonca zahodiť celé \(n\).

Ak chceme zahodiť logaritmus, môžeme si všimnúť, že celé čo robíme je bitový OR všetkých \(b_i\) v intervale. To vieme urobiť triviálne lineárne. A teda okrem toho zisťujeme najvyšší bit, ktorý je zapnutý aspoň v dvoch číslach. Toto sa tiež dá efektívne urobiť troškou bitovej mágie. Už máme premennú \(O\), ktorá si udržiava OR všetkých zatiaľ spracovaných čísel. Zadefinujme si okrem toho \(D\). To vždy pri spracovaní prvku \(b_i\) updateneme na \(D \operatorname{OR} (O \operatorname{AND} b_i)\). Teda do neho vždy pridáme bity, ktoré sme už niekedy predtým videli ale aj sú nastavené v aktuálnom čísle, čo je presne čo chceme. Teda nakoniec si v \(D\) nájdeme najvyšší zapnutý bit a všetky nižšie bity v odpovedi zapneme.

Takto sme teda dosiahli zložitosť \(O(qn)\), čo je ale stále príliš pomalé. Ďalšia optimalizácia by mala ale byť každému skúsenému KSPákovi jasná – máme nejaké updatey a nejaké query na intervale (s asociatívnou kombinačnou funkciou) , takže na to proste hodíme intervaláč. Takto dosiahneme zložitosť \(O(n + q \log n)\), ktorá získa dva body.

Späť k pôvodnej úlohe

No a teraz sa ešte potrebujeme zbaviť obmedzenia \(a_i = 0\). Na to použijeme jedno veľmi pekné pozorovanie – pozrime sa na spoločný prefix čísel \(a_i\) a \(b_i\) v binárke. Vieme, že každé číslo v intervale \([a_i, b_i]\) má tiež tento prefix. Teda akúkoľvek hodnotu si vyberieme, tento prefix nedokážeme zmeniť. Nazvime si tieto bity fixnuté. No a tu nadchádza ďalšie pozorovanie – ingorujúc prípad \(a_i = b_i\), ktorý vieme triviálne vyriešiť, sa tieto čísla musia na prvej cifre po prefixe líšiť. To ale znamená, že v tomto intervale je aj toto \(b_i\), aj číslo, ktoré má na tejto líšiacej pozícií nulu a nižšie jednotky. Tiež ak je na niektorej nižšej pozícií jednotka, vieme ju vynulovať a nižšie dať jednotky.

No a tak sa nám rysuje riešenie: najprv si pre každé \(i\) spočítame najdlhší zhodný prefix \(a_i\) a \(b_i\). Následne si hodnoty \(b_i\) rozdelíme na tento prefix a zvyšok. Tieto dve časti si uložíme do intervaláča. Pri vykonávaní query si najprv vyORujeme tieto fixné prefixy. A následne už len pokračujeme v riešení prípadu \(a_i = 0\), akurát začíname s \(O\) nastaveným na OR fixných prefixov a pracujeme len na zvyškoch.

Ešte by sme si mohli myslieť, že sa nám v zložitosti opäť objaví \(\log A\) pri hľadaní najdlhšieho zhodného prefixu, avšak tomu sa vieme jednoducho vyhnúť tak, že \(a_i\) a \(b_i\) vyXORujeme a nájdeme najvyšší nastavený bit, čo moderné CPU zvládnu v konštantnom čase.

Toto riešenie má zložitosť \(O(n + q \log n)\) a získa plné body. Pamäťová zložitosť je \(O(n)\).

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ť.