3 - Smeštaj
Vremensko ograničenje | Memorijsko ograničenje |
---|---|
1500ms | 512MB |
Postoji \(N\) osoba i \(M\) soba. Osobe mogu rezervisati sobe, ali ni u jednom trenutku neće dve osobe imati rezervisanu istu sobu, dok svaka osoba uvek ima najviše jednu rezervisanu sobu. Na početku niko nema ništa rezervisano. U nekim momentima se vrši simuliranje raspoređivanja po sobama, na osnovu trenutnih rezervacija, i to funkcioniše na sledeći način:
- Za svaku osobu, redom od \(1\) do \(N\), se odlučuje koja će joj soba biti dodeljena, nakon čega je do kraja raspoređivanja ta soba zauzeta.
- Ukoliko osoba \(U\) nije rezervisala sobu, ona dobija sobu sa najmanjim indeksom koja nije ni zauzeta ni rezervisana.
- Ukoliko je osoba \(U\) rezervisala sobu, ona dobija sobu sa manjim indeksom između sobe koju je rezervisala i sobe sa najmanjim indeksom koja nije ni zauzeta ni rezervisana. Ukoliko \(U\) nije dobila sobu koju je rezervisala, ta rezervacija prestaje da važi do kraja raspoređivanja i soba koju je \(U\) bila rezervisala postaje slobodna.
Dato je i \(Q\) upita, svaki upit je jedan od sledeća dva tipa:
-
\(1\) \(U\) \(X\). Osoba \(U\) rezerviše sobu \(X\). Ukoliko je \(U\) pre toga imala neku drugu rezervaciju, ta rezervacija se poništava. Ukoliko je \(X = 0\), tada se samo poništava rezervacija sobe osobe \(U\). Garantuje se da za \(X \neq 0\) nijedna osoba nema rezervisanu sobu \(X\) u ovom trenutku.
-
\(2\) \(U\). Simulira se raspoređivanje po sobama na opisani način. Treba odgovoriti na pitanje u kojoj sobi će završiti osoba \(U\), ukoliko bi se izvršila simulacija raspoređivanja u sobe po opisanom algoritmu, uzevši u obzir sve upite tipa \(1\) do ovog upita, ali ne uzimajući u obzir prethodne upite tipa \(2\). Dakle, nakon ovog upita su ponovo sve sobe prazne i važe iste rezervacije koje su važile neposredno pre upita. Ukoliko ne postoji soba u koju osoba \(U\) može da uđe, odgovor je \(-1\).
Opisi funkcija
Potrebno je da implementirate funkciju
- \(Smestaj(N, M, Q, T[\dots], U[\dots], X[\dots], Ans[\ldots])\)
gde je \(N\) broj osoba, \(M\) broj soba, \(Q\) broj upita, \(T_i\) tipovi upita, \(U_i\) osoba koja rezerviše sobu u upitu tipa \(1\), odnosno osoba za koju treba naći odgovor u upitu tipa \(2\), \(X_i\) soba koju osoba \(U_i\) rezerviše u upitu tipa \(1\), i \(Ans\) niz u koji treba upisati odgovore na upite tipa \(2\). Svi nizovi su indeksirani od \(1\). Niz \(Ans\) je takođe indeksiran od \(1\), odgovor na \(i\)-ti upit tipa \(2\) treba da bude u \(Ans_i\). Ako je \(T_i = 2\), garantuje se da važi \(X_i = 0\).
Primer
Neka je \(N=5\), \(M=8\), \(Q=7\) i neka su dati upiti:
Tada:- U prvom upitu treba pronaći koju će sobu dobiti osoba \(2\):
- Osoba \(1\) dobija sobu, slobodne su \(\{1,2,3,4,5,6,7,8\}\). Kako osoba \(1\) nije rezervisala sobu, ona dobija sobu \(1\).
- Osoba \(2\) dobija sobu, slobodne su \(\{2,3,4,5,6,7,8\}\). Kako osoba \(2\) nije rezervisala sobu, ona dobija sobu \(2\). Dakle, \(Ans_1 = 2\).
- U drugom upitu osoba \(3\) rezerviše sobu \(1\).
- U trećem upitu treba pronaći koju će sobu dobiti osoba \(2\):
- Osoba \(1\) dobija sobu, slobodne su \(\{2,3,4,5,6,7,8\}\). Kako osoba \(1\) nije rezervisala sobu, ona dobija sobu \(2\).
- Osoba \(2\) dobija sobu, slobodne su \(\{3,4,5,6,7,8\}\). Kako osoba \(2\) nije rezervisala sobu, ona dobija sobu \(3\). Dakle, \(Ans_2 = 3\).
- U četvrtom upitu osoba \(2\) rezerviše sobu \(2\).
- U petom upitu treba pronaći koju će sobu dobiti osoba \(2\):
- Osoba \(1\) dobija sobu, slobodne su \(\{3,4,5,6,7,8\}\). Kako osoba \(1\) nije rezervisala sobu, ona dobija sobu \(3\).
- Osoba \(2\) dobija sobu, slobodne su \(\{4,5,6,7,8\}\). Kako je osoba \(2\) rezervisala sobu \(2\), a soba koja je slobodna sa najmanjim indeksom je soba \(4\), ona dobija sobu \(2\). Dakle, \(Ans_3 = 2\).
- U šestom upitu osoba \(3\) rezerviše sobu \(5\). Njena prethodna rezervacija sobe \(1\) se poništava.
- U sedmom upitu treba pronaći koju će sobu dobiti osoba \(3\):
- Osoba \(1\) dobija sobu, slobodne su \(\{1,3,4,6,7,8\}\). Kako osoba \(1\) nije rezervisala sobu, ona dobija sobu \(1\).
- Osoba \(2\) dobija sobu, slobodne su \(\{3,4,6,7,8\}\). Kako je osoba \(2\) rezervisala sobu \(2\), a soba koja je slobodna sa najmanjim indeksom je soba \(3\), ona dobija sobu \(2\).
- Osoba \(3\) dobija sobu, slobodne su \(\{3,4,6,7,8\}\). Kako je osoba \(3\) rezervisala sobu \(5\), a soba koja je slobodna sa najmanjim indeksom je soba \(3\), ona dobija sobu \(3\). Dakle, \(Ans_4 = 3\).
Dakle, za ovaj primer važi:
- \(T = [2,1,2,1,2,1,2]\)
- \(U = [2,3,2,2,2,3,3]\)
- \(X = [0,1,0,2,0,5,0]\)
- \(Ans = [2,3,2,3]\)
Ograničenja
- \(1 \leq N,M,Q \leq 300.000\)
- \(N \leq M\)
- \(1 \leq U_i \leq N\)
- \(0 \leq X_i \leq M\)
- Garantuje se da ni u jednom trenutku dve osobe neće imati rezervisanu istu sobu.
Podzadaci
Test primeri su podeljeni u \(7\) podzadatka:
- [5 poena]: \(N,M,Q \leq 500\)
- [7 poena]: \(N,M \leq 1.000, Q \leq 20.000\)
- [6 poena]: \(N,M \leq 1.000, Q \leq 200.000\)
- [11 poena]: \(N,M,Q \leq 300.000, X_i \leq 30\)
- [14 poena]: \(N,M \leq 8.000, Q \leq 300.000\)
- [23 poena]: \(N,M \leq 100.000, Q \leq 100.000\)
- [34 poena]: Nema dodatnih ograničenja
Detalji implementacije
Potrebno je da pošaljete tačno jedan fajl smestaj.cpp
koji implementira pomenutu funkciju. Osim tražene funkcije, vaš fajl može sadržati i dodatne globalne promenljive, pomoćne funkcije i dodatne biblioteke.
Vaša funkcija mora biti sledećeg oblika:
void Smestaj(int N, int M, int Q, int *T, int *U, int *X, int *Ans);
Vašim programima je dozvoljeno da menjaju sadržaj nizova/matrica, ali ne smeju da pristupaju van granica datih nizova.
Uz zadatak, obezbeđen vam je "template" fajl code.cpp
koje možete koristiti i menjati po potrebi. Takođe vam je obezbeđen program grader.cpp
koji služi da lakše testirate kodove. Ovaj program učitava sa standardnog ulaza sledeće podatke:
- U prvom redu brojeve \(N, M, Q\),
- U narednih \(Q\) redova po jedan upit.
Zatim ovaj program zove vašu funkciju i štampa odgovre koje vaša funkcija upiše u niz Ans
.
Autor | Tekst i test primeri | Analiza rеšenja | Testiranje |
---|---|---|---|
Aleksa Milisavljević | Aleksa Milisavljević | Aleksa Milisavljević | Vladimir Milenkovic |
Podzadatak 1: \(N,M, Q \leq 500\)
U ovom podzadatku dovoljno je simulirati rešenje, tako što ćemo u svakom upitu proći kroz svih \(n\) osoba i za svaku osobu proveriti koja je slobodna soba sa najmanjim indeksom. Složenost: \(O(NMQ)\).
Podzadatak 2: \(N,M \leq 1.000, Q \leq 20.000\)
U ovom podzadatku možemo da radimo sličnu simulaciju, kao i u prethodnom, samo što ćemo u "std::set" ubaciti sve slobodne sobe i potom za svaku osobu izabrati ili njenu rezervaciju (ukoliko je ima i manja je od prvog elementa seta) ili najmanji element u setu. Ukoliko izaberemo element iz seta, izbacujemo ga, a ubacujemo rezervaciju (ukoliko je ima). Složenost: \(O(QN \log M)\).
Podzadatak 3: \(N,M \leq 1.000, Q \leq 200.000\)
U ovom podzadatku možemo da radimo sličnu simulaciju, ali tako što ćemo, umesto čuvanja skupa slobodnih soba, u svakom trenutku pamtiti pokazivač na poslednju slobodnu sobu. Složenost: \(O(QN)\).
Koju sobu će izabrati osoba \(X\)?
Lema: Prvih \(X\) osoba će popuniti prvih \(X\) nerezervisanih soba, ukoliko samo posmatramo sobe koje su rezervisale osobe posle osobe \(X\).
Ova lema se može lako pokazati indukcijom i razdvajanjem na slučajeve da li je osoba \(X+1\) rezervisala sobu i gde se ta soba nalazi u odnosu na poslednju zauzetu sobu. Sada lako vidimo da će osoba \(X\) da izabere ili \(X\)-tu slobodnu sobu, ukoliko posmatramo rezervacije soba posle osobe \(X\) ili sobu koju je ona rezervisala (ako je ima). Odavde vidimo i da će za svaku osobu uvek biti bar jedna slobodna soba, tj. odgovor nikada neće biti \(-1\).
Podzadatak 4: \(N,M,Q \leq 300.000, X_i \leq 30\)
U ovom podzadatku je dovoljno za svaku sobu zapamtiti koja osoba ju je rezervisala. Potom u upitu za \(U_i \leq 30\) simuliramo odabir sobe kao u podzadatku 3, a za preostale proverimo koliko soba su rezervisale osobe sa indeksima većim od \(U_i\). Složenost: \(O(Q \max X_i)\).
Podzadatak 5: \(N,M \leq 8.000, Q \leq 300.000\)
Za ovaj podzadatak je potrebna struktura podataka 2d segmentno stablo u kojem pamtimo za interval osoba \([l,r]\) i interval soba \([x,y]\) koliko soba iz tog intervala nije rezervisala ni jedna osoba iz intervala \([l,r]\). Potom binarno pretražujemo po rešenju najmanje \(t\), tako da u intervalu \([1,t]\) ima bar \(U_i\) nerezervisanih soba, ukoliko posmatramo rezervacije osoba iz intervala \([U_i + 1, N]\). Složenost: \(O(Q \log N \log^2 M)\).
Podzadatak 6: \(N,M \leq 100.000, Q \leq 100.000\)
U ovom podzadatku koristimo istu ideju kao i u prethodnom, ali zbog velikog broja osoba i soba, moramo da koristimo implicitno 2d segmentno stablo. Složenost: \(O(Q \log N \log^2 M)\).
Podzadatak 7: \(N,M \leq 300.000, Q \leq 300.000\)
U ovom podzadatku optimizujemo ideju iz prethodnog zadatka. Naime, možemo da primetimo da nam je \(\log\) od binarne pretrage višak i da možemo da se "šetamo" po implicitnom 2d segmentnom stablu. Ovo radimo tako što zapamtimo skup segmentnih stabala koja se odnose na osobe posle osobe \(U_i\) i potom u se u njima šetamo tako što pronađemo sumu brojeva slobodnih soba u levom podstablu svakog. Ukoliko je ta suma veća ili jednaka sa \(k = U_i\), onda idemo u to podstablo u svakom stablu iz skupa, u suprotnom idemo u desno i od \(k\) oduzmemo sumu iz levih. Složenost: \(O(Q \log N \log M)\).
03_smestaj.cpp | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
|