Sunteți pe pagina 1din 4

În această lecție vom prezenta 3 aplicații ale descompunerii numerelor în factori

primi interesante ce vor face rezolvarea unor anumite cerințe din problemele de
informatică mult mai ușoară , dar și eficientă din punct de vedere al timpului și
memoriei.

Determinarea numărului de divizori ai unui număr


O prima metodă de aflare a numă rului de divizori ai unui numă r dat n este
parcurgerea intervalului [2,𝑛2] numă râ nd valorile ce reprezintă un divizor
pentru numă rul n. Este eficientă ?

O soluție mult mai eficientă constă în folosirea urmă toarei propietă ți. Vom
folosi ca notații:

𝑝 – factorul prim
𝑒 – exponentul factorului prim.

Pentru numă rul n ce are descompunerea în factori


𝑛=𝑝1𝑒1⋅𝑝2𝑒2⋅…….⋅𝑝𝑘𝑒𝑘,numă rul de divizori poate fi calculat utilizâ nd formula:
(𝑒1+1)⋅(𝑒2+1)⋅…….⋅(𝑒𝑘+1)
Să luă m ca exemplu numă rul 36. Descompunerea în factori primi a acestuia este:
36=22⋅32
Divizorii acestuia sunt: 1,2,3,4,6,9,12,18,36 – 9 divizori.

Aplică m propietatea de mai sus. Luă m exponentul primului factor prim. Adună m
cu 1 și înmulțim cu exponentul urmă torului avâ nd grijă ca acesta să fie adunat
tot cu 1.

𝐷36=(2+1)*(2+1)
𝐷36=3*3
𝐷36=9 => Obținem că numă rul 36 are 9 divizori.
int nrDiv(int a)
{
/*
In e stocam exponentul factorului prim pe care il parcurgem
d - Reprezinta factorul prim gasit
rez - Rezultatul final */
int e,d,rez;
e=0; // Initializam exponentul cu 0
while(a%2==0) //Luam cazul special: singurul numar prim par este 2.
{
a/=2;
e++;
}
/*Initializam rezultatul cu primul exponent gasit.
Chiar daca exista sansa ca 2 sa nu fie factor prim al numarului
caruia dorim sa ii gasim numarul divizorilor rezultatul tot este initializat
cu 1 fiindca exponentul este initializat cu 0.
*/
rez=e+1;
d=3; //Urmatorul nr. prim este 3.
while(a>1 && d*d<=a) /*Parcurgem intervalul [2, radical(n)]*/
{
e=0;
while(a%d==0)
{
a/=d;
e++;
}
//Inmultim la rezultat exponentul gasit.
//Nu uitam sa fie adunat cu 1.
rez*=(e+1);
d+=2;
}
if(a&gt;1)
rez*=2;
return rez; //Final.
}
Suma divizorilor unui număr
O soluție reprezintă determinarea divizorilor în mod asemă nă tor ca mai sus, însă
adună m divizorii într-o variabilă .

Pentru a afla mult mai repede suma divizorilor unui numă r vom folosi
urmă toarea propietate:

Pentru numă rul n ce are descompunerea în factori 𝑛=𝑝1𝑒1⋅𝑝2𝑒2…….⋅𝑝𝑘𝑒𝑘,suma


divizorilor poate fi calculată utilizâ nd formula:
(𝑝1𝑒1+1−1)/(𝑝1−1)*(𝑝2𝑒2+1−1)/(𝑝2−1)*…….*(𝑝𝑘𝑒𝑘+1−1)/(𝑝𝑘−1)

Să luă m ca exemplu tot numă rul 36. Ș tim că descompunerea acestuia în factori
primi este 36=22∗32. Divizorii acestuia sunt: 1,2,3,4,6,9,12,18,36-suma acestora
este 91.

Acum să aplică m proprietatea enunțată mai sus:

𝑆36=2(2+1)−1/(2−1)*(3(2+1)−1)/(3−1)

𝑆36=(23−1)/1*(33−1)/2
𝑆36=7⋅26/2
𝑆36=7⋅13=91
𝑆36=91 => Suma divizorilor numă rului 36 este 91.

O implementare în C++:

#include <iostream>
using namespace std;
int SumDiv(int n) {
int e, p, d;
e = 1;
p = 1;
while (n % 2 == 0) {
n /= 2;
e *= 2;
}

e *= 2;
e--;

p = e;

for (d = 3; n > 1 && d * d <= n; d += 2) {


e = 1;

while (n % d == 0) {
n /= d;
e *= d;
}

e *= d;
e--;

e = e / (d - 1);
p *= e;
}

if (n > 1)
p *= (1 + n);

return p;
}
int main()
{int x=36;
cout<<SumDiv(x);

return 0;
}

Indicatorul Euler
Indicatorul Euler( sau funcția totent ) determină numărul de valori mai
mici sau egale cu un număr dat și prime cu acesta. Aceasta se notează 𝜙(𝑛) și
se poate afla aplicâ nd urmă toarea propietate:

Pentru numă rul n ce are descompunerea în factori 𝑛=𝑝1𝑒1⋅𝑝2𝑒2…….⋅𝑝𝑘𝑒𝑘,


indicatorul Euler se poate afla utilizâ nd urmă toarea formulă :
𝜙(𝑛)=𝑛⋅(1−1/𝑝1)⋅(1−1/𝑝2)⋅……⋅(1−1/𝑝𝑘)
Să luă m ca exemplu numă rul 9. Acesta are descompunerea în factori primi 9=32.
Aplică m indicatorul Euler pentru a afla numă rul de valori prime cu acesta.
𝜙(9)=9⋅(1−1/3)
𝜙(9)=6 => 6 valori sunt prime cu acesta.
O implementare în C++:

int Indicatorul_Euler(int n)
{
int i,euler=n;
if(n==1) //Caz special cand n=1 returnam 0
return 0;
if(n%2==0) //Singurul nr prim par 2...
{
euler -= euler/2; //Aplicam formula lui euler de mai sus.
while(n%2==0)
n/=2;
}
for(i=3; i*i<=n; i+=2) //Factorii sunt primi deci daca am gasit 2 ca fiind factor
prim, acela fiind singurul par, cautam doar cei impari
{
if(n%i==0)
{
euler -= euler/i; //De asemenea...
while(n%i==0)
n/=i;
}
}
if(n>1)
euler -= euler/n;
return euler;
}

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