Zadanie

Samo a Jano sú influenceri. Od čokofirmy dostali masívnu reklamnú obojstrannú tubu rôznofarebných čokoládiek pre dvojičky. Vraj aby sa odfotili, ako im chutí a aké skvelé to je, že sa nemusia hádať, kto si vytiahne čokoládu prvý. Každý vie, že rôzne farby čokoládiek znamenajú rôzne obsiahnuté živiny. Keďže Samo a Jano chcú všetkým ukázať, ako vyvážene sa stravujú, zrátali si, koľko ktorých čokoládiek chcú zjesť. Dve purpurové, šesť egyptských modrých, jedna nachová, tri indigové, sedem sivých…

Tuba s čokoládkami je otvorená z dvoch strán. Samo a Jano začali zbesilo vyťahovať čokošky z jednej strany. Keď nejakú vytiahnú, tak ju rovno aj zjedia, aj keď nepatrí do ich požiadaviek na vyváženú stravu. Keby ju nezjedli, určite by sa niekde stratila. To by bola škoda. Rýchlo si však uvedomili, že čím viac nechcených čokoládiek zjedia, tým horšiu mienku o nich budú mať ich sledovatelia.

Nuž, Samo začal hútať, koľko čokoládiek z ktorej strany to majú vlastne vybrať, aby sa najedli čo najmenej, ale aby zároveň uspokojili svoje potreby vyváženej stravy. Ak budú musieť tých zlých čokolád zjesť priveľa, nebudú ani chcieť pristúpiť na takúto ponuku sponzora. A podobných ponúk určite príde ešte veľa. Hodil by sa im preto program, ktorý pre danú tubu čokoládiek a ich potreby vyváženej stravy vypočíta, koľko najmenej čokoládiek budú musieť vytiahnúť, aby sa dostali k tým, čo chcú. Pomôžete im udržať priazeň publika?

Úloha

Tuba je priehľadná a otvorená z dvoch strán. Vnútri sú čokoládky naskladané v rade vedľa seba. Samo a Jano chcú vybrať z tuby aspoň \(a_1\) čokoládiek farby \(f_1\), aspoň \(a_2\) čokoládiek farby \(f_2\), …, aspoň \(a_m\) čokoládiek farby \(f_m\).

Vašou úlohou je zistiť, koľko najmenej čokoládiek musia dokopy z tuby vybrať tak, aby splnili svoje požiadavky. V každom momente môžu vybrať buď čokoládku úplne zľava, alebo čokoládku úplne sprava.

Formát vstupu

Na prvom riadku dostanete čísla \(n\) - počet všetkých čokoládiek v tube, \(m\) - počet Samových a Janových požiadaviek a \(f\) - počet rôznych farieb čokoládiek, ktoré sa môžu vyskytovať v tube. Platí, že \(1 \leq f \leq n \leq 500\,000\) a \(0 \leq m \leq f\).

Na druhom riadku je \(n\) čísiel \(c_1\)\(c_n\) - farby čokoládiek tak, ako sú v tube zľava doprava. Farby majú čísla od \(1\) po \(f\). To však neznamená, že sa na vstupe musia nutne vyskytovať všetky farby od \(1\) po \(f\).

Nasleduje \(m\) riadkov. V \(i\)-tom z nich sú čísla \(a_i\) a \(f_i\). Tie znamenajú, že Samo a Jano chcú z tuby vybrať aspoň \(a_i\) čokoládiek farby \(f_i\). Môžete predpokladať, že všetky \(f_i\) sú navzájom rôzne a tiež, že pre zadanú tubu sú všetky požiadavky vždy splniteľné.

Formát výstupu

Na výstup vypíšte jedno číslo - koľko najmenej čokoládiek musia Samo s Janom z tuby vybrať, aby splnil všetky svoje požiadavky.

Príklady

Input:

6 2 3
1 2 2 1 3 2
1 1
3 2

Output:

4

Naši súrodenci chcú jednu čokoládu farby 1 a tri čokolády farby 2. Môžu teda zobrať napríklad 3 čokolády zľava a jednu sprava.

Input:

5 1 3
1 2 2 3 1
1 2

Output:

2

Teraz chcú iba jednu čokoládu farby 2. Tá ale nie je na kraji, tak sa k nej musia dostať cez najľavejšiu čokoládu farby 1.

Iba jedna strana

Pozrime sa, ako by sa úloha zmenila, keby sme mohli brať čokolády iba zľava. Skúsme všetky možnosti a pre každú overme, či vyhovuje. Najskôr teda overíme, či nám stačí zobrať iba prvú čokoládu. Potom skúsime zobrať prvú a druhú, potom skúsime prvú, druhú a tretiu… Z vyhovujúcich možností zoberieme tú najkratšiu. Ako ale zistiť, či možnosť vyhovuje?

Pre každú testovanú možnosť si zrátame, koľko čokolád ktorej farby obsahuje. Majme pole \(p\) veľkosti \(f\) so samými nulami. Číslo \(p_i\) nám hovorí, koľko čokolád farby \(i\) momentálne máme. Ak zoberieme čokoládu farby \(u\), tak ku \(p_u\) pripočítame \(1\). Keď si teda napočítame čokolády v testovanom úseku, môžeme prejsť všetky požiadavky a pre každú požiadavku overiť, či je splnená. Takéto riešenie jednoduchšej úlohy bude fungovať v čase \(O(n(n + m + f))\), pretože pre každú z \(n\) možností prejdeme nanajvýš \(n\) políčok, vynulujeme pole \(p\) veľkosti \(f\) a prejdeme všetkých \(m\) požiadaviek.

Iba jedna strana, rýchlejšie

V pôvodnom riešení sme veľa vecí robili zbytočne. Napríklad, ak sme už poznali počty čokolád v úseku \([1,\,x]\) a chceli sme zistiť počty čokolád v úseku \([1,\,x+1]\), nemuseli sme nulovať celé pole \(p\). Úplne nám stačí pridať do poľa \(p\) čokoládu na pozícií \(x+1\). Všetky ostatné čokolády totiž budú tie isté, ako v starom úseku. Ku \(p_{c_{x+1}}\) teda iba pripočítame \(1\). Teraz, keď nezahadzujeme informácie zo skúmania predchádzajúcej možnosti, vieme každú novú možnosť spracovať v \(O(m)\). Možností je stále \(n\), takže časová zložitosť je \(O(f + nm)\). Stále totiž pre každú možnosť prechádzame cez všetky požiadavky. Pole \(p\) však nastavujeme už iba raz.

Iba jedna strana, ešte rýchlejšie

Asi je celkom očividné, že slabou časťou nášho doterajšieho riešenia je to, že pre každú možnosť prechádzame všetky požiadavky, aby sme overili, či sú splnené. Ako to zlepšiť?

Vieme, že keď sme ešte nezobrali žiadnu čokoládu, tak nie je splnená žiadna požiadavka. Majme teda počítadlo \(nesplnene\), ktoré bude hovoriť, koľko máme ešte nesplnených požiadaviek. Na začiatku, je samozrejme nastavené na \(m\). Postupne pridávame čokolády, až niekedy nastane zaujímavá udalosť. Pridaním čokolády farby \(w\) sa nám mohol zvýšiť počet týchto čokolád na minimálnu hranicu požadovanú Samom a Janom. To znamená, že požiadavka na čokolády farby \(w\) doteraz nebola splnená, ale teraz už splnená je. Môžeme teda od \(nesplnene\) odčítať \(1\).

Keď niekedy \(nesplnene\) dosiahne hodnotu \(0\), vieme, že už sú všetky požiadavky splnené. Nemusíme teda už ani skúšať brať ďalšie čokolády. Určite by sme tým už nenašli lepšie riešenie, ako máme teraz.

Ako ale zistiť, že nejaká požiadavka doteraz nebola splnená a teraz už je? Na začiatku si spravíme pole \(t\) veľkosti \(f\), ktoré nám pre každú farbu povie, koľko jej je žiadanej. To vieme spraviť už počas načítavania požiadaviek. Potom s týmito hodnotami vieme porovnávať hodnoty z poľa \(p\). Ak doteraz platilo, že \(p_i < t_i\) a zobratím nejakej čokolády farby \(i\) začalo platiť, že \(p_i = t_i\), tak požiadavka na farbu \(i\) je už splnená. Časová zložitosť teda bude \(O(n + m + f)\).

Dve strany, hrubá sila

Jednoduchým riešením pôvodnej úlohy je vyskúšať všetky možnosti pre zobratie prefixu a suffixu a každú takúto možnosť overiť. Podľa toho, ako dobre spravíme overovanie môže mať toto riešenie časovú zložitosť zhruba niekde medzi \(O(n^2)\) a \(O(n^3)\). Rôzne spôsoby overovania sme si popísali vyššie.

Dve strany, vzorové riešenie

Poďme sa ale pozrieť, ako môžeme riešenie úlohy, kde berieme čokolády iba zľava rozšíriť na obojstrannú verziu.

V jednoduchšej úlohe sme spravili pozorovanie, že ak vieme splniť požiadavky najľavejšími \(x\) čokoládami, tak už nemusíme skúšať brať ďalšie, pretože by sme tým určite nezískali lepšie riešenie. Ako toto pozorovanie využiť? Nuž, skúsme nezobrať žiadne čokolády sprava. Zľava teraz zoberieme iba toľko čokolád, koľko nám stačí na splnenie všetkých požiadaviek. Máme teda nejaké riešenie. Možno je najlepšie, možno nie, no určite spĺňa všetky požiadavky. No dobre, zľava už určite nechceme zobrať viac čokolád.

Čo ale sprava? Čo sa môže stať, keď zoberieme naviac ešte jednu čokoládu sprava? Ak to bola čokoláda, ktorej farba sa nijak nevyskytuje v požiadavkách, tak nič neriešime. Zhoršili sme si síce doterajšie riešenie, ale to nás nijak netrápi, pretože výsledok lepšieho riešenia si pamätáme ako doteraz najlepšie nájdené. Čo sa ale stane, ak sa farba najpravejšej čokolády nachádza niekde v požiadavkách na vyváženú stravu? Znamená to, že možno môžeme na ľavú stranu vrátiť čokoládu, ktorú sme odtiaľ zobrali ako poslednú. Môžeme ju vrátiť, ak má rovnakú farbu, ako tá, ktorú sme teraz zobrali sprava. No a aby sme sa z ľavej strany dostali k čokoláde, ktorú sme tam teraz vrátili, museli sme možno prejsť cez nejaké čokolády, ktoré sme vôbec nechceli. Môžeme tam teda vrátiť aj tie. A ľaľa, možno sme práve našli nové najlepšie riešenie.

Pozrime sa na to naopak. Máme riešenie, ktoré berie čokolády iba zľava. Vieme, že všetky požiadavky sú splnené. Skúsme vrátiť čokoládu, ktorú sme zobrali ako poslednú. Tým možno prestala byť splnená nejaká požiadavka. To znamená, že teraz budeme brať čokolády sprava, až kým neopravíme túto pokazenú požiadavku. Tento postup teda začne s riešením, ktoré berie iba čokolády zľava a opakuje dva jednoduché kroky:

  1. Vráť na ľavú stranu čokoládu, ktorú si odtiaľ zobral ako poslednú
  2. Ber čokolády sprava, kým opäť nie sú splnené všetky požiadavky

Môžeme si všimnúť, že niekedy nám vrátenie čokolády na ľavú stranu žiadnu požiadavku nepokazí. Vtedy teda nemusíme brať žiadne ďalšie čokolády sprava.

Akú to má celé časovú zložitosť? Najskôr nájdeme nejaké riešenie, ktoré berie čokolády iba zľava. To už vieme v \(O(n + m + f)\). Potom vždy vrátime jednu čokoládu na ľavú stranu a zoberieme niekoľko, možno aj 0, čokolád sprava. Každú čokoládu teda najviac raz zoberieme a najviac raz vrátime. Bude to teda celé v \(O(n + m + f)\). Vieme ale, že \(m\) ani \(f\) nikdy nebudú väčšie, ako \(n\). Môžeme teda povedať, že časová zložitosť je \(O(n)\).

Pamäťová vyzerá ako \(O(n + m + f)\). Požiadavky si ale nemusíme pamätať ako zoznam, takže sa dostávame na \(O(n + f)\) a stále platí, že \(f \leq n\), takže aj o pamäti môžeme povedať, že 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ť.