Sunteți pe pagina 1din 8

RoAlgo Contest 5 - Editorial

S, tefan-Cosmin Dăscălescu, Matei Ionescu,


Theodor Pirnog, Traian Mihai Danciu

5 Noiembrie 2023

1 Mult, umiri
Acest concurs nu ar fi putut avea loc fără următoarele persoane:

• Matei Ionescu, Theodor Ioan Pirnorg, Traian Mihai Danciu, autorii prob-
lemelor s, i laureat, i la concursurile de informatică s, i membri activi ai co-
munităt, ii RoAlgo.
• Alex Vasilut, ă, fondatorul s, i dezvoltatorul principal al Kilonova
• Andrei Chertes, Ioana Frant, , testerii concursului, care au dat numeroase
sugestii s, i sfaturi utile pentru buna desfăs, urare a rundei.

• S, tefan-Cosmin Dăscălescu, coordonatorul rundei, s, i autorul solut, iilor video.


• Comunităt, ii RoAlgo, pentru participarea la acest concurs.

2 Problema nr9
Autor: Matei Ionescu

2.1 Solut, ia oficială


Observat, ia necesară este că dacă n nu este divizibil cu 9, oricum am rearanja
cifrele lui n obt, inem un număr care nu este divizibil cu 9. Acest lucru se
ı̂ntâmplă deoarece restul ı̂mpărt, irii lui n la 9 este dat de restul ı̂mpărt, irii
sumei cifrelor lui n la 9. Atunci, dacă n nu este divizibil cu n, putem afis, a
direct n, altfel vom afis, a n − 1, deoarece n − 1 nu este divizibil cu 9 dacă n
este. Complexitate: O(1) timp s, i O(1) memorie.

1
2.2 Cod sursă s, i solut, ie video
Solut, ie de 100
Solut, ie video

3 Problema divnr
Autor: Traian Mihai Danciu

3.1 Solut, ia oficială


Solut, ia se bazează pe faptul că putem afis, a un număr de forma x · 10k (x
urmat de k zero-uri), unde x este cel mai mic multiplu comun al tuturor
numerelor din s, ir, iar k = m − numărul de cifre al luix. Din moment ce x este
cel mai mic astfel de număr, s, i există un număr pentru fiecare test, deducem
că m ≥ numărul de cifre al luix. Deci solut, ia este corectă. Complexitate:
O(n + m) timp s, i O(1) memorie, pentru fiecare test.
Desigur există s, i alte solut, ii, precum afis, area numărului 10m−1 + (x − (10m−1
mod x)).

3.2 Cod sursă s, i solut, ie video


Solut, ie de 100
Solut, ie video

4 Problema muxusetre
Autor: Traian Mihai Danciu

4.1 Solut, ia oficială


Fie zi = numărul de 0 până la i. Fie ui = numărul de 1 până la i. Pentru ca
secvent, a [l, r] să fie bună, trebuie să avem zl−1 − ul−1 = zr − ur (mod 2).
O observat, ie importantă este că zi − ui ̸= zi+1 − ui+1 . Acest lucru se
ı̂ntâmpla, deoarece când adăugam al i + 1-lea caracter, exact unul dintre zi+1
s, i ui+1 ı̂s, i schimbă paritatea când trecem de la i la i + 1 (deoarece adunăm 1 la
exact unul dintre ele). Atunci diferent, a ı̂s, i va schimba paritatea.
Încă o observat, ie care ne duce spre solut, ie este că z1 − u1 = ±1. Atunci
rezultă că zi − ui = i (mod 2).

2
Deci problema se reduce la aceasta: Se dă un număr n, ı̂n câte moduri putem
lua 2 indici care să aibă aceeas, i paritate (observat, i că aici este inclus s, i 0).
Pentru a rezolva această problemă nouă, trebuie doar să numărăm cât, i indici
pari avem (notat cu p), s, i câti indici impari avem (notat cu i):
p = ⌊ n2 ⌋ + 1
i = ⌈ n2 ⌉
Iar acum putem lua doi indici pari ı̂n p·(p−1)2 , iar cu impari ı̂n mod
i·(i−1)
asemănător: 2 . S, i adunând aceste două numere, obt, inem rezultatul.
Complexitate: O(n) timp (deoarece trebuie să citim s, i s, irul, ca să aflăm
următorul n) s, i O(1) memorie, pentru fiecare subtest.
Solut, ia care ret, ine numerele zi s, i ui ı̂n 2 variabile, pe care le actualizeaza, va
lua s, i ea punctajul maxim, dar având ı̂n vedere ce am spus mai sus, nu este
nevoie de acele 2 variabile.

4.2 Cod sursă s, i solut, ie video


Solut, ie de 100
Solut, ie video

5 Problema 3secv
Autor: Traian Mihai Danciu

5.1 Solut, ia oficială


Ne putem folosi câteva variabile, ı̂n care ret, inem cele 3 valori distincte din
secvent, a curentă, s, i unde au apărut ultima oară. Când ı̂ntâlnim o valoare
diferită de cele 3, o ı̂nlocuim pe cea care a apărut ulima oară cel mai târziu cu
noua valoare. Complexitate: O(n) timp, O(1) memorie.

5.2 Cod sursă s, i solut, ie video


Solut, ie de 100
Solut, ie video

6 Problema Dorel coadă de purcel


Autor: Traian Mihai Danciu

3
6.1 Solut, ia oficială
Pentru a obt, ine răspunsul optim, trebuie să afis, ăm numai cifre prime. De ce
este optim? Pentru că, de exemplu, dacă am avea a = 8, atunci dacă am afis, a
b = 8, am avea 7!, s, i cu 8, dar ar fi mai optim să afis, ăm b = 7222, pentru că
are mai multe cifre.
Apoi precalcula numerele prime până la n folosind ciurul lui Eratostene. Vom
descompune ı̂n factori primi ai ! (1 ≤ i ≤ k), folosindu-ne de formula lui
Legendre.
Apoi putem itera prin numerele prime ı̂n ordine descrescătoare, afis, ând
numerele de câte ori ne spune frecvent, a numărului curent, iar apoi actualizăm
frecvent, a numerelor mai mici tot folosind formula lui Legendre.
Pentru mai multe detalii legate de implementare accesat, i link-ul de mai jos de
la solut, ia de 100. Complexitate: O(n2 / log n + k · n) timp (deoarece sunt
n / log n numere prime, formula lui Legendre pentru fiecare cifră este
O(n / log n · log n) = O(n), iar formula lui Legendre pentru fiecare număr
prim este tot O(n / log n · log n) = O(n)), s, i O(n) memorie (pentru ciur,
numere prime, s, i frecvent, ă)

6.2 Cod sursă s, i solut, ie video


Solut, ie de 100
Solut, ie video

7 Problema cuvinte
Autor: Theodor Ioan Pirnog

7.1 Solut, ia oficială


Expresia se va evalua folosind o stivă sau cu ajutorul recursivităt, ii indirecte.
Se vor extrage parametrii fiecărei funct, ii (care pot fi simpli:
reverse(”exemplu”) sau compus, i: reverse(order(”exemplu”))). Odată s, tiute
funct, ia s, i parametrii ei, se poate trece la prelucrarea aferentă fiecărei funct, ii.
Complexitate: O(N ∗ 100).

7.2 Cod sursă s, i solut, ie video


Solut, ie de 100
Solut, ie video

4
8 Problema joingraf
Autor: Traian Mihai Danciu

8.1 Solut, ii part, iale


Pentru subtaskurile 1, 2, 3, 4 este suficientă o abordare care foloses, te arbori de
intervale cu lazy.

8.2 Solut, ia oficială


Pentru a rezolva această problemă, trebuie mai ı̂ntâi să observăm că
componentele conexe sunt ca nis, te intervale. De exemplu, să luăm n = 7.
Atunci, la ı̂nceput intervalele vor fi: [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7].
Dacă unim muchiile de la 3 la 6, intervalele vor deveni: [1, 1], [2, 2], [3, 6], [7, 7].
Atunci, putem folosi o structură de tip pădure de mult, imi disjuncte. Vom
ret, ine pari = ”părintele” nodului i, sau mai us, or de ı̂nt, eles, capătul stânga al
intervalului ı̂n care este nodul i. Este nevoie să ret, inem doar capătul dreapta,
deoarece capătul dreapta al secvent, ei curente este predecesorul capătului
stânga al secvent, ei următoare. Vom ret, ine s, i nxti = capătul stânga al
secvent, ei de după secvent, a ı̂n care este i.
Iar atunci când avem update cu x, y, mergem la fiecare secvent, ă până la y
(adică când avansăm de la p la următoarea, facem p = nxtp ) s, i o reunim cu
secvent, a ı̂n care este x.
Iar la query, verificăm dacă intervalul ı̂n care este x este egal cu cel ı̂n care este
y. Complexitate: O(N + Q log N ) timp, O(n) memorie.

8.3 Solut, ie alternativă


Putem, ı̂n loc să folosim păduri de mult, imi disjuncte, să folosim un set. Iar
update-ul s, i query-ul se implementează asemănător cu solut, ia oficială.

8.4 Cod sursă s, i solut, ie video


Solut, ie de 100
Solut, ie alternativă
Solut, ie video

5
9 Problema suxumetre
Autor: Matei Ionescu
Vom simplifica mai intai problema prin precalcularea costului pe fiecare
interval ı̂mparte.
O idee ar fi sa fixăm un i s, i să ret, inem suma pe intervalul [i, j], mod m, s, i
atunci putem pentru fiecare k de la 1 la m să numărăm câte interval cuprinse
intre [i, j] se termină ı̂n j s, i au suma mod m = k. Dacă s, tim că
Suma(l = i)( j) = A mod m, atunci numarul de intervale care se termină in J
s, i au suma mod m = k va fi dat de pozitiile unde sph = (A + mod − k)
mod m. Ca să le numărăm putem să ret, inem un vector de frecvent, ă cu M
elemente.

9.1 Solut, ii part, iale


9.1.1 Subtask 1: 10 puncte

Putem sa folosim backtracking ca sa găsim o ı̂mpărt, ire optimă ı̂n k secvent, e


disjuncte s, i nevide sau ne putem ajuta de bitmask-uri iar bit, ii setat, i vor
delimita cele K intervale. Observăm că vom avea nevoie de K + 2 bis, i (vom
pune un bit pe pozitia 0 si unul pe pozitia n + 1); Complexitatea temporală:
O(2n · n);

9.1.2 Subtask 2 si 3: 40 puncte

Ne vom folosi de dinamica dpi,j = costul minim ca să ı̂mpărt, im primele j


elemente. Recurent, a reiese astfel: dpj,i = min(dpj−1,k + C(k + 1, i);
Complexitate temporală: O(n2 · k)

9.2 Solut, ia oficială


Dinamicele de genul sunt foarte clasice, chiar au o optimizare foarte faină.
Pentru un dp cum ar fi dpi,j = min(dpi−1,k + C(k + 1, j) denotăm opt(i, j) ca
fiind ”the optimum splitting point” ca fiind k-ul care minimizeaza dpi,j .
Atunci putem spune că opt(i, j − 1) ≤ opt(i, j) pt oricare (i, j) doar dacă
oricum am alege patru indici (a, b, c, d), C(a, b) + C(b, d) ≤ C(a, d) + C(b, c);
Putem deci sa dezvoltăm un algoritm tip ”divide and conquer” unde vom
ı̂mpărt, i succesiv vectorul ı̂n 2 intervale [st, mij], [mij + 1, dr] s, i să calculăm
dp-ul pentru mij ı̂n intervalul [opt(i, st), opt(i, dr)].
Această optimizare se numes, te ”divide and conquer dp” si putet, i citi mai
multe de pe linkul acesta. Complexitatea finală: O(k · n log n)

6
9.3 Cod sursă s, i solut, ie video
Solut, ie de 100
Solut, ie video

10 Problema cucuruz
Autor: Matei Ionescu
Practic problema ne ı̂ntreabă care este suma valorilor de pe fiecare lant, cu
lungimea mai mică sau egală cu P . Restrict, ia cu W < D este pusă pentru a
sugera că nu se numără acelas, i drum de 2 ori.

10.1 Solut, ii part, iale


10.1.1 Subtaskturile [1, 2, 3, 4], 30 puncte

Putem sa precalculăm sumele part, iale pentru fiecare nod s, i să fixăm oricare 2
noduri, verificăm dacă distant, a dintre cele 2 noduri este mai mică sau egală cu
p s, i adunăm la rezultat suma de pe lantul respectiv; Complexitate: O(n2 log n)

10.1.2 Subtask 5 : 20 puncte

Putem să ne calculăm ı̂n cnt(nod, i) suma de pe toate lant, urile care ı̂ncep ı̂n
nod s, i se termina ı̂ntr-un nod din subarborele lui cu distant, a i s, i ı̂n pl(nod, i)
câte noduri din subarborele lui nod sunt la distant, ă i fat, ă de nod.
Acuma putem pentru fiecare nod să ne calculăm suma totala pentru lant, urile
care ı̂ncep ı̂n subarborele lui nod, trec prin nod s, i se termină tot ı̂n subarborele
lui nod.
Fie f1 , f2 , f3 , . . . , fk tot, i fii lui nod. Dacă ne alegem un nod fi s, i o distant, ă pi ,
atunci putem să aflăm suma cnt(fk , pk ) s, i pl(fk , pk ), cu k < i s, i pi + pk ≤ P s, i
să adunăm la rezultat suma + cnt(fi , pi ) · suma1; Pentru a optimiza aflarea
sumei s, i a numărului de noduri aferente, putem să folosim 2 arbori indexat, i
binar. Complexitate: O(p · n log n)
Putem să ret, inem doar sumele part, iale s, i atunci complexitatea devine O(n ∗ p).

10.1.3 Subtask 6: 10 puncte

Putem face acelas, i lucru ca la subtask ul anterior, doar că P = 2 s, i atunci


putem să calculăm totul in O(n)

7
10.2 Solut, ia oficială
Putem reimplementa ideea de la subtask-ul 5 doar ca vom aborda diferit
problema s, i ne vom folosi de o tehnică foarte utilă numită ”Centroid
Decomposition”. O idee bună ar fi să aflăm centroidul arborelui init, al.
Aplicăm ideea de la subtaskul 5, eliminăm centroidul din arbore si apelăm
recursiv pentru fiecare subarbore rezultat.
De ce complexitatea devine O(n · log 2 n)? Mai ı̂ntâi hai să clarificăm ce este
un centroid. Un centroid este un nod pe care dacă-l eliminăm, numărul de
noduri din subarborii rezultat, i sunt mai mici sau egali cu N/2, unde N e
numărul de noduri din arborele init, ial.
Astfel dacă descompunem arborele eliminând centroizii, atunci fiecare nod va
apart, ine de maxim O(log n) componente conexe pe parcursul descompunerii.
Astfel complexitatea se poate exprima ca O(log n) · f (N ) unde f (N ) este
timpul necesar pentru a afla toate lant, urile bune care trec prin fiecare centroid.
f (N ) = O(n log n) deorece trebuie să precalculăm matricea cnt pentru fiecare
nod din componenta respectiva ·log n (de la aib-uri). Putem scăpa de matricea
cnt dacă luăm doar suma de la A la centroidul respectiv (că ne este ı̂ndeajuns).

10.3 Cod sursă s, i solut, ie video


Solut, ie de 100
Solut, ie video

S-ar putea să vă placă și