Sunteți pe pagina 1din 4

Există o serie de probleme pentru care rezolvarea lor se rezumă la aflarea exponentului

unui număr dat k,exp(k)k,exp(k) , într-un produs factorial (n!)(n!), fără a calcula acel


produs.
O metodă naivă ar fi căutarea multiplior lui k mai mici sau egali cu n și de câte ori de
divid acestia cu k.
Exemplu:
n=75,k=7n=75,k=7
n!=1∗2∗3∗4∗5∗6∗7∗…∗14∗…∗21∗…∗28∗…∗35∗…∗42∗…∗49∗…∗56∗…
∗63∗…∗70∗…∗75n!=1∗2∗3∗4∗5∗6∗7∗…∗14∗…∗21∗…∗28∗…∗35∗…∗42∗…∗49∗…
∗56∗…∗63∗…∗70∗…∗75
n!=1∗…∗1∗7∗…∗2∗7∗…∗3∗7∗…∗4∗7∗…∗5∗7∗…∗6∗7∗…∗7∗7∗…
∗8∗7∗…∗9∗7∗…∗7∗10∗…∗75n!=1∗…∗1∗7∗…∗2∗7∗…∗3∗7∗…∗4∗7∗…∗5∗7∗…
∗6∗7∗…∗7∗7∗…∗8∗7∗…∗9∗7∗…∗7∗10∗…∗75 exp(7)=11exp(7)=11
O soluție ar fi parcurgerea intervalului [k,n][k,n]cu pasul kk și contorizarea multiplilor.
C++
______________________________
exp=0

for (int i=k;i<=n;i+=k)

int x=i;

while(x%k==0)

{exp++;x/=k;}

cout<<exp;
___________________________
Termenul dominant este T(n) ->n/k (algoritm linear).
O altă soluție ar fi folosirea unei formule de calcul a exponentului lui kk în n!
n! notat expn!(k)expn!(k), numită formula lui Legendre.
Dacă numărul k este prim expn!(k)=[nk]+[nk2]+[nk3]+…expn!(k)=[nk]+[nk2]+
[nk3]+…
Exemplu:n=75,k=7n=75,k=7
exp75!(7)=[757]+[7549]+[75343]=10+1+0=11exp75!
(7)=[757]+[7549]+[75343]=10+1+0=11
Se poate deduce că după un anumit număr de pași raportul va deveni subunitar ceea ce
determină că suma va avea un număr finit de termeni. Pornind de la această relație,
valoarea acelui exponent se poate calcula însumând câturile împărțirilor succesive.
Implementarea C++.
________________________________________
exp=0

while(n>=k)
{

n=n/k;

exp+=n;

}
________________________________________
Termenul dominant este T(n) ->log(n) (algoritm logaritmic)
Dacă numărul kk este un număr compus și în descompunerea în factori primi se obține
produsul k=de11⋅de22⋅…⋅dellk=d1e1⋅d2e2⋅…⋅dlel unde d1,d2,…,dld1,d2,…,dl sunt
factorii primi iar e1,e2,…,ele1,e2,…,el exponenții acestora, vom folosi relațiile
matematice (1) și (2), unde:
expn!(de)=[expn!(d)e]expn!(de)=[expn!(d)e](1)
expn!(k)=min{expn!(de11),expn!(de22),expn!(de33),…expn!(dell)}expn!
(k)=min{expn!(d1e1),expn!(d2e2),expn!(d3e3),…expn!(dlel)}(2)
Exemplu:
n=75,k=12n=75,k=12
12=22⋅312=22⋅3
exp75!(22)=[exp75!

(2)2]=([752]+[754]+[758]+[7516]+[7532]+[7564]+[75128])/2=(37+28+4+1+0

)/2=35exp75!(22)=[exp75!
(2)2]=([752]+[754]+[758]+[7516]+[7532]+[7564]+[75128])/2=(37+28+4+1+0)/2=35.
exp75!(3)=[753]+[759]+[7527]+[7581]=25+8+2+0=35exp75!
(3)=[753]+[759]+[7527]+[7581]=25+8+2+0=35.
În concluzie,
 exp75!(12)=min(35,35)=35exp75!(12)=min(35,35)=35
Implementare C++
________________________________________
int a,b,divi[100],puterea[100],poz,minim;

int putere(int n,int p)

int x=0;

while(n>p)

x+=n/p;

n=n/p;

return x;
}

int main()

f>>b>>a;

int d=2;

while(d*d<=a)

if(a%d==0)

divi[++poz]=d;

int c=0;

while(a%d==0)

a/=d

puterea[poz]++; }}

d++;

if(a!=1)

divi[++poz]=a;

puterea[poz]=1;

minim=1000000;

for(int i=1;i<=poz;i++)

puterea[i]=putere(b,divi[i])/puterea[i];

if(minim>puterea[i])

minim=puterea[i];

}
g << minim;

return 0;

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