Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- Problema propusa va folosi urmatoarele :
- - Cautare binara pe rezultat
- - Fereastra glisanta / sliding window technique
- Enunt pe scurt : Se sorteaza crescator toate sumele
- subsecventelor dintr-un sir de valori si le punem
- intr-un tablou v. Se cere afisarea elementului v[k].
- Ex : sir : 1,2,4 , k = 5
- Subsecventele si sumele lor sunt :
- (1)-> 1
- (1,2)-> 3
- (1,2,4)-> 7
- (2)-> 2
- (2,4)-> 6
- (4) -> 4
- Sumele sortate sunt :
- 1 , 2 , 3, 4 , 6 , 7.
- V[k] = 6. (k=5)(Raspunsul).
- Sa spunem ca avem n elemente.
- Vom avea n*(n+1)/2 subsecvente
- (in exemplu n = 3 -> 3*4/2 = 6 subsevente)
- Din restrictii n <= 10.000 asadar putem avea
- pana la 50 de milioane de subsecvente...
- Evident nu putem simula ce ne cere problema
- (eu nu propun probleme foarte usoare in caz de a-ti observat)
- REZOLVARE
- F(x) - returneaza cate subsecvente sunt mai mici sau egale cu x;
- Daca stim aceasta informatie stim a cata subsecventa este ultima subsecventa cu suma x.
- Deci daca gasim cel mai mic x pentru care F(x) >= k atunci si elementul k din sirul sortat
- va avea aceiasi suma;
- Sa luam un sir sortat de sume ale subsecventelor sa intelegem mai bine :
- Sir 1 2 4 6 6 6 8 10 (suma = 43)
- Poz 1 2 3 4 5 6 7 8 (Vrem sa returnam Sir[5] = 6 (acel 6 de la mijloc.)
- Cand f(x) >= k vom salva acea pozitie evident.
- k = 5 , cand F(x) < k -> st = mid+1, cand F(x) >= k -> dr = mid-1 si salvam mid ca noua solutie.
- st = 1 , dr = 43 -> mid = 21 -> F(x) = 8 (evident toate sumele sunt mai mici decat 21) (noua solutie = mid)
- st = 1, dr = 20 -> mid = 10 -> F(x) = 8 (iarasi) (noua solutie = mid)
- st = 1, dr = 9 -> mid = 5 -> F(x) = 3 (de la pozitia 4 incolo sunt mai mari sumele decat 5)
- st = 6, dr = 9 -> mid = 7 -> F(x) = 6 (noua solutie = mid)
- st = 6, dr = 6 -> mid = 6 -> F(x) = 6 (noua solutie = mid)
- st = 6, dr = 5 -> exit. sol = 6
- De aceea luam f(x)>=k si nu doar f(x)==k, pentru ca putem avea mai multe subsecvente cu aceiasi suma.
- Acum sper ca reiese cum ne ajuta functia F(x) si cum putem folosi rezultatele ei in cautarea binara
- pentru a determina valoarea sumei de pe pozitia k. Dar pana acum am folosit doar rezultatele functiei din ochi
- pentru ca putem vedea din datele exemplului..
- Acum complexitatea solutiei va fi logN ( de la cautarea binara) * ceva (complexitatea functiei F(x))
- Dar stim deja ca n^2 nu este suficient de eficient deci e clar ca complexitatea necesara functiei F(x)
- este O(n)... Deci cam printr-o singura trecere a elementelor va trebui sa spunem cate subsecvente
- au suma mai mica sau egala decat x. Nu avem asa de multe optiuni de considerat. E clar ca vom
- avea nevoie de fereastra glisanta / sliding window technique.
- Vom retine suma elementelor de la i la j. Cand mutam i suma scade , cand mutam j suma creste.
- Asadar daca suma de la i la j <= x atunci toate subsecventele cu j fixat acolo si cu i crescand
- pana la j vor avea si ele suma mai mica sau egala decat x (suma scade) deci putem din start
- sa crestem sol cu lungimea intervalului (j - i + 1).
- Daca suma de la i la j este mai mare decat x atunci mutam i pana cand suma este mai mica sau egala.
- Aveti aici functia F(x) in cod.
- */
- int F(int x)
- {
- int sol = 0; // cate subsecvente au suma mai mica sau egala decat x
- int i = 1, j = 1, // cei doi pointeri
- int sum = 0; // suma de la i la j
- while(i<=n&&j<=n)
- {
- sum+=v[j];
- while(sum>x) //ne asiguram ca suma e mai mica sau egala decat x.
- sum-=v[i], i++; //mutam capatul din stanga al intervalului.
- sol+=(j - i + 1); //crestem sol cu lungimea intervalului.
- j++;
- }
- return sol;
- }
Add Comment
Please, Sign In to add comment