4 - Bombonice
Vremensko ograničenje | Memorijsko ograničenje |
---|---|
2000ms | 512MB |
Mala Duca mnogo voli da jede bombonice. Ona je od svoje mame dobila beskonačno bombonica i sada želi da ih rasporedi u kutije. Uzela je \(N\) praznih kutija, napisala na njima brojeve od \(1\) do \(N\), i postavila ih redom u krug oko sebe. Kutiji sa rednim brojem \(N\) susedne kutije su sa rednim brojevima \(N-1\) i \(1\).
Sada će stavljati bombonice u kutije na sledeći način: Izabraće dva broja, \(P\) i \(K\), i onda će u kutiju broj \(P\) dodati tačno \(K^2\) bombinca (zato što voli brojeve koji su potpuni kvadrati), zatim će u sledeću kutiju redom u krugu dodati \((K-1)^2\) bombonica, zatim u sledeću \((K-2)^2\), itd. redom dok ne prođe \(K\) kutija i u poslednju stavi jednu (\(1^2\)) bombonicu. Ovakav postupak, počev od ponovnog izbora novih brojeva \(P\) i \(K\), će potencijalno ponavljati više puta, sve dok joj ne dosadi.
Duca želi da održava određeni balans bombonica u nekim kutijama, tako da će se povremeno zapitati koliko je ukupno bombonica ubacila u nekih \(T\) uzastopnih kutija, počev od kutije broj \(X\). Kako to može biti jako veliki broj za računanje, moli vas za pomoć da joj svaki put odgovorite na ovakvo pitanje, i za uzvrat će vam dati nekoliko bombonica. Ukoliko svi odgovori budu tačni, pomoći će vam i da osvojite neki poen na takmičenju.
Opisi funkcija
Potrebno je da implementirate sledeće funkcije:
- \(Pocetak(N)\)
koja se poziva tačno jednom na početku izvršavanja programa, i saopštava da Duca ima \(N\) kutija postavljenih u krug.
- \(DodajBombonice(P,K)\)
koja označava da Duca dodaje bombonice u \(K\) kutija, počev od kutije broj \(P\), na način koji je opisan u zadatku.
- \(Prebroji(X,T)\)
koja treba da vrati koliko se trenutno ukupno bombonica nalazi u \(T\) uzastpnih kutija, počev od kutije broj \(X\). Pošto ovaj broj može biti veliki, vratiti ostatak pri deljenju broja bombonica sa \(10^9 + 7 = 1000000007\).
Primer 1
Pozivi funkcija | Objašnjenje |
---|---|
Pocetak(7) | Imamo 7 kutija koje su na početku prazne. Broj bombonica u njima možemo |
predstaviti kao niz indeksiran od 1: [0,0,0,0,0,0,0] | |
DodajBombonice(2,3) | Dodajemo \(9=3^2\) bombonica u drugu kutiju, \(4=2^2\) bombonica u treću |
kutiju i \(1=1^2\) bombonicu u četvrtu kutiju. Sada je stanje: [0,9,4,1,0,0,0] | |
DodajBombonice(4,2) | Dodajemo \(4\) bombonice u četvrtu i \(1\) bombonicu u petu kutiju. |
Trenutno stanje: [0,9,4,5,1,0,0] | |
DodajBombonice(5,4) | Dodajemo \(16\) bombonica u petu, zatim \(9\) u šestu, \(4\) u sedmu, i \(1\) u prvu kutiju. |
Trenutno stanje: [1,9,4,5,17,9,4] | |
Prebroji(1,5) | Brojimo koliko ima bombonica u 5 uzastopnih kutija počev od prve. |
[1,9,4,5,17,9,4] Ovaj poziv funkcije treba da vrati rezultat 36. | |
Prebroji(5,1) | Brojimo koliko ima bombonica u 1 uzastopnoj kutiji počev od pete. |
[1,9,4,5,17,9,4] Ovaj poziv funkcije treba da vrati rezultat 17. | |
DodajBombonice(7,2) | Dodajemo \(4\) bombonice u sedmu i \(1\) bombonicu u prvu kutiju. |
Dobijamo stanje: [2,9,4,5,17,9,8] | |
Prebroji(6,4) | Brojimo koliko ima bombonica u \(3\) uzastopne kutije počev od šeste. |
[2,9,4,5,17,9,8]Ovaj poziv funkcije treba da vrati rezultat 28. |
Ograničenja
- Neka je \(Q\) ukupan broj poziva funkcija \(DodajBombonice\) i \(Prebroji\).
- \(1 \leq N, Q \leq 250000\)
- \(1 \leq P,K,X,T \leq N\)
Podzadaci
- Podzadatak 1 [11 poena]: \(N, Q \leq 1000\).
- Podzadatak 2 [18 poena]: \(K \leq 3\).
- Podzadatak 3 [19 poena]: \(T \leq 3\).
- Podzadatak 4 [20 poena]: Prvo će se izvršavati samo pozivi funkcije \(DodajBombonice\), potom nakon njih samo pozivi funkcije \(Prebroji\)
- Podzadatak 5 [32 poena]: Nema dodatnih ograničenja.
Detalji implementacije
Potrebno je da pošaljete tačno jedan fajl bombonice.cpp
ili bombonice.pas
, koji implementira pomenute funkcije. Osim traženih funkcija, vaš fajl može sadržati i dodatne globalne promenljive, pomoćne funkcije i dodatne biblioteke.
U zavisnosti od programskog jezika koji koristite, vaše funkcije/procedure moraju biti sledećeg oblika:
Jezik | Deklaracija funkcije |
---|---|
C++ | void Pocetak(int N); |
void DodajBombonice(int P, int K); |
|
int Prebroji(int X, int T); |
|
Pascal | procedure Pocetak(N: longint); |
procedure DodajBombonice(P,K : longint); |
|
function Prebroji(N,T : longint) : longint; |
Testiranje i eksperimentisanje
Uz zadatak, obezbeđeni su vam "template" fajlovi code.cpp
i code.pas
koje možete koristiti i menjati po potrebi. Takođe su vam obezbeđeni programi grader.cpp
, grader.pas
koji služe da lakše testirate kodove. Ovi programi učitavaju sa standardnog ulaza sledeće podatke:
- U prvom redu učitava brojeve \(N\) i \(Q\)
- Poziva funkciju \(Pocetak(N)\)
- U narednih \(Q\) redova čita po 3 broja
-
- Prvi broj je tip upita (1 - dodavanje bombonica, 2 - prebrojavanje)
-
- U prvom slučaju, preostala dva broja su \(P\) i \(K\), i poziva se funkcija \(DodajBombonice(P,K)\)
-
- U drugom slučaju, preostala dva broja su \(X\) i \(T\), i poziva se funkcija \(Prebroji(X,T)\), i ispisuje se njen rezultat, svaki u posebnom redu.
Kodove ovih programa možete menjati po potrebi.
Autor | Tekst i test primeri | Analiza rеšenja | Testiranje |
---|---|---|---|
Ivan Stošić | Ivan Stošić | Ivan Stošić | Aleksa Plavšić |
Lako se zaključuje da se pri dodavanju bombonica, one dodaju u kutije \(P, P+1, P+2, ..., P+K-1\). Za nijansu je jednostavniji slučaja kada je \(P+K-1\leq N\). Ako uvedemo oѕnaku \(R=P+K\), onda će u kutiju broj \(I\) (\(P\leq I\leq P+K-1=R-1\)) biti dodato \((R-I)^2\) bombonica, Ako uzmemo u obzir da je \((R-I)^2 = R^2 - 2R\times I + I^2\), to broj dodatih kuglica možemo baš posmatrati kao tri zasebna sabirka (koji će formirati tokom trajanja tri zasebna zbira). Da bi efikasno mogli da efikasno ažuriramo zbirove (po pojedinačnim kutijama) i efikasno određuejmo zbirove blokova uzastopnih kutija, formiramo tri segmentna stabla. Jedno koje zbraja fiksni sabirak u operaciji dodavanja (\(R^2\)), drugo koje broji koliko smo puta sadržaj \(I\)-te kutije uvećali za \(I\) (u gornjem primeru to je \(-2R\)) i treće koje broji koliko smo puta sadržaj \(I\)-te kutuje uvećali za \(I^2\) (u gornjem primeru to je \(1\)). Ako ta segemntna stabla formiramo na taj način, onda ćemo kasnije moći efikasno da prebrojimo ukupan broj bombonica u blokovima uzastopnih kutija.
Ako je \(P+K-1> N\), onda dodavanje bombonica razdvajamo u dva dodavanja: u prvom dodavanju je \(P1=P\) \(K1=N-P+1\), a u drugom je \(P2 = 1\) i \(K2=K-K1\).
Slično se prebrajanje bombonica razdvaja na dva slučaja. Ako je \(X+T-1\leq N\), onda je dovoljan jedno sabiranje po segmentnom stablu za blok (interval) \(X,X+T-1]\). Ako je \(X+T-1.>N\), onda su potrebna dva upita/zbira: ѕa intervale \(X, N]\) i \([1,T-(N+1-X)]\).
04_bombonice.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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
|