1. Teorema Fundamentala a Aritmeticii
n = p₁e₁ × p₂e₂ × … × pkek
unde p₁ < p₂ < … < pk sunt numere prime, iar e₁, e₂, …, ek sunt exponentii lor (≥ 1).
- 12 = 2 × 2 × 3 = 22 × 3
- 60 = 2 × 2 × 3 × 5 = 22 × 3 × 5
- 72 = 2 × 2 × 2 × 3 × 3 = 23 × 32
Cuvantul-cheie este prim: factorizarea contine DOAR numere prime. “12 = 4 × 3” NU este o factorizare in factori primi, deoarece 4 = 22 nu este prim.
2. Algoritmul de factorizare in Python — O(√n)
Bucla exterioara merge pana la √n. Daca n = 106, facem cel mult 1000 de pasi. Daca n ar mai avea un factor prim p > √n, celalalt factor q = n/p < √n ar fi fost gasit deja in bucla — contradictie. Deci poate fi cel mult un astfel de factor, prins la final cu if n > 1.
# Factorizare: n = 60 def factorizare(n): factori = {} # dictionar: factorul prim -> exponent d = 2 while d * d <= n: # O(sqrt(n)) while n % d == 0: # cat timp d divide n factori[d] = factori.get(d, 0) + 1 n //= d # elimina un factor d d += 1 if n > 1: # factorul prim mare ramas factori[n] = factori.get(n, 0) + 1 return factori n = 60 f = factorizare(n) print("Factorizarea lui 60:") for p, e in sorted(f.items()): print(f" {p}^{e}") termeni = [f"{p}^{e}" if e > 1 else str(p) for p, e in sorted(f.items())] print("60 =", " * ".join(termeni))
Factorizarea lui 60: 2^2 3^1 5^1 60 = 2^2 * 3 * 5
d=2: 12 % 2 == 0 → factori[2]++, n = 6
d=2: 6 % 2 == 0 → factori[2]++, n = 3
d=2: 3 % 2 != 0 → d devine 3
d=3: 3*3 = 9 > 3 → bucla while d*d ≤ n se opreste
n = 3 > 1 → factori[3]++ (factorul mare ramas)
Rezultat: 12 = 22 × 3
3. Numarul si suma divizorilor prin formule
Numarul de divizori: d(n) = (e₁+1)(e₂+1)…(ek+1)
Suma divizorilor: σ(n) = ∏ (pe+1−1) / (p−1)
- d(60) = (2+1)(1+1)(1+1) = 3 × 2 × 2 = 12
- σ(60) = (23−1)/(2−1) × (32−1)/(3−1) × (52−1)/(5−1) = 7 × 4 × 6 = 168
# Calcul numar si suma divizori folosind factorizarea def factorizare(n): factori = {} d = 2 while d * d <= n: while n % d == 0: factori[d] = factori.get(d, 0) + 1 n //= d d += 1 if n > 1: factori[n] = factori.get(n, 0) + 1 return factori def nr_divizori(factori): rezultat = 1 for e in factori.values(): rezultat *= (e + 1) # formula (e+1) return rezultat def suma_divizori(factori): rezultat = 1 for p, e in factori.items(): rezultat *= (p**(e+1) - 1) // (p - 1) # serie geometrica return rezultat n = 60 f = factorizare(n) print(f"60 = 2^2 * 3 * 5") print(f"Numar de divizori: {nr_divizori(f)}") print(f"Suma divizorilor: {suma_divizori(f)}")
60 = 2^2 * 3 * 5 Numar de divizori: 12 Suma divizorilor: 168
4. Generarea listei divizorilor — O(√n)
i=1: 24/1=24 → (1, 24) | i=2: 24/2=12 → (2, 12) | i=3: 24/3=8 → (3, 8) | i=4: 24/4=6 → (4, 6) | i=5: nu divide | i=5: 5*5=25>24, stop.
# Lista tuturor divizorilor lui n def divizori_lista(n): divs = [] i = 1 while i * i <= n: # O(sqrt(n)) if n % i == 0: divs.append(i) if i != n // i: # evita dublarea la patrate perfecte divs.append(n // i) i += 1 return sorted(divs) print("Divizorii lui 24:", divizori_lista(24)) print("Numar:", len(divizori_lista(24)))
Divizorii lui 24: [1, 2, 3, 4, 6, 8, 12, 24] Numar: 8
24 = 23 × 3, deci d(24) = (3+1)(1+1) = 4 × 2 = 8. Coincide cu lungimea listei de mai sus.
5. Aplicatii: numere speciale prin divizori
- Numar perfect: suma divizorilor proprii (fara n insusi) = n. Exemplu: 1+2+3 = 6 → 6 este perfect.
- Numar prim: exact 2 divizori (1 si el insusi). Legatura cu factorizarea: d(p) = 2 ⇔ p prim.
- Numar patrat perfect: are un numar impar de divizori (divizorul de la mijloc = √n).
# Verifica daca n este numar perfect def este_perfect(n): s = sum(i for i in range(1, n) if n % i == 0) return s == n for n in [6, 12, 28, 36]: print(f"{n} este perfect: {este_perfect(n)}")
6 este perfect: True 12 este perfect: False 28 este perfect: True 36 este perfect: False
6. Factorizare in C++ cu map EXCLUSIV INTENSIV
La profilul intensiv implementam factorizarea in C++ folosind map<int,int> (echivalentul dict din Python) si structured bindings din C++17 (auto& [p, e]). Acelasi algoritm O(√n), alta sintaxa.
#include <iostream> #include <map> using namespace std; map<int, int> factorizare(int n) { map<int, int> f; for (int d = 2; d * d <= n; d++) { while (n % d == 0) { f[d]++; n /= d; } } if (n > 1) f[n]++; return f; } int main() { int n = 360; auto f = factorizare(n); cout << "360 = "; bool first = true; for (auto& [p, e] : f) { // C++17 structured bindings if (!first) cout << " * "; cout << p << "^" << e; first = false; } cout << endl; int nd = 1; for (auto& [p, e] : f) nd *= (e + 1); cout << "Numar de divizori: " << nd << endl; return 0; }
360 = 2^3 * 3^2 * 5^1 Numar de divizori: 24
360 = 23 × 32 × 51, deci d(360) = (3+1)(2+1)(1+1) = 4×3×2 = 24. Coincide cu outputul programului.