Sunteți pe pagina 1din 2

Descrierea soluției – abx

Autor
prof. Nistor Moț
Colegiul Național ”N. Bălcescu”, Brăila

Soluție 40p:

Pentru fiecare număr x din șirul dat trebuie să căutăm cea mai apropiată putere, deci vom avea de
efectuat N căutări. Pentru a căuta răspunsul pentru un număr dat x, vom avansa în cele două direcții
(dreapta, stânga) până numărul de la pasul curent este putere. Mai apoi, îl vom afișa pe cel mai
apropiat dintre cele două.

Pentru a verifica dacă un număr y este putere , o variantă este descompunerea lui y în factori primi.
Dacă cel mai mare divizor comun al exponenților este mai mare decât 1, y este o putere.

Este esențială observația că nu are rost să verificăm de mai multe ori dacă un număr este putere sau
nu. În acest context, putem precalcula pentru fiecare număr din intervalul [1,m] dacă acesta este
putere și stoca acest lucru într-un vector caracteristic.

O soluție care rezolvă problema în complexitate O(M*(N+M)) ar trebui să obțină cel puțin 40 de
puncte.

Soluție 70p:

Vom considera o variantă diferită de a genera toate puterile din intervalul [1,m]: considerăm fiecare
bază posibilă a și adăugăm ab pornind cu b de la valoarea 2 și incrementându-l cât timp ab nu
depășește m. Se observă că șirul rezultat va avea mai puțin de 50.000 de puteri (eliminând
duplicatele). Pentru a găsi cele două puteri apropiate de x, vom sorta vectorul, eliminând duplicatele și
vom efectua o căutare binară pe acest vector sortat.

Se poate demonstra că complexitatea acestei soluții este O(sqrt(M)+N*log(M)). O astfel de soluție


ar trebui să obțină cel puțin 70 de puncte.

Soluție 90p:

Pentru subtask-ul M ≤ 1018 se poate observa că soluția de 70 de puncte nu se mai încadrează în


limitele de timp și de memorie. Pentru a rezolva problema în acest caz, există mai multe abordări; toate
aceste abordări ar trebui să obțină punctajul maxim, dacă sunt implementate cu atenție:

Căutare binară: Pentru un exponent b fixat, se poate afla baza maximă a pentru care ab ≤ x. Mai apoi,
singurii candidați pentru răspuns sunt ab sau (a+1)b. Complexitatea algoritmului de căutare binară
este O(b*log(M)) (exponențiere iterativă) sau O(log(b)*log(M)) (exponențiere logaritmică). O
soluție care caută binar cele două puteri pentru fiecare exponent posibil (2 ≤ b ≤ 60) folosind
exponențierea iterativă are complexitate O(N log2(M)) și ar trebui să obțină 90 de puncte. În
continuare vom prezenta optimizări extra, care îmbunătățesc și mai mult timpul de execuție.

Considerarea doar a exponenților primi: O optimizare substanțială a soluției anterioare o constituie


observația că, pentru a considera toate puterile posibile, este suficient să considerăm doar exponenții
care sunt primi, deoarece dacă n = ab, cu b = db’, atunci n = (ab’)d, deci orice putere de
exponent b va fi considerată în cadrul exponentului d. În intervalul [2,60] sunt doar 17 numere prime.

Abordare hibridă: O altă soluție o reprezintă precalcularea puterilor pentru b ≥ 4 într-o manieră similară
soluției de 70 de puncte și folosirea căutării binare pentru cazul b = 2 sau b = 3. Această soluție are
complexitate O(sqrt(sqrt(M))+N*log(M)). Menționăm că o astfel de soluție va obține un timp de
execuție foarte bun, nedepășind 0.1 secunde pe un test maximal.

Posibile greșeli:

Erori de precizie: Menționăm că folosirea unei abordări floating-point (folosirea funcției pow) este
înceată și poate conduce la erori substanțiale de precizie; astfel, nu este recomandată să fie folosită în
cadrul soluției, dar cu puțină atenție poate fi folosită cu succes, mai ales pentru valori mici de-ale lui M.

Erori de overflow: În abordarea de 90 de puncte, ne vom întâmpina de problema overflow-ului, care


trebuie tratată cu grijă. O variantă simplă de a evita astfel de erori este ca, la fiecare înmulțire a*b să
verificăm mai întâi dacă a*b ≤ M. Cum a*b poate da rezultate eronate, vom verifica ca a ≤ M/b. O
soluție care nu tratează corect overflow-ul va putea obține între 70-90 de puncte în funcție de alte detalii
de implementare.

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