Pagini recente » Cod sursa (job #1971854) | Cod sursa (job #2335764) | Cod sursa (job #25766) | Cod sursa (job #1755796) | Cod sursa (job #2045758)
/**
Un mod mai eficient de calculare a numauluide diizori si a sumei divizoilor este
folosindu-ne de aritmtica modulara si ridicareea la putere in timp logaitmic
Astfel:
- formam ciurul si simultan sirul care contine numerele prime a BINE
Pentru ficare numar vom calcula:
-numarul de divizori(mod normal) BUN;
-suma o vom calcula dupa formula, folosindu-ne de ridicare la putere in timp logaritmic a
lui a^n si invesul modular al numarului a-1; unde a este divizorul prim si n este exponentul
acestuia
***/
#define MOD 9973
#include <cstdio>
using namespace std;
char c[1000002];
int a[78500];
void formam_ciurul()
{
for(int i=2;i<=1000005;i++)
{
if(c[i]==0)
{
for(int j=i*2;j<=1000005;j+=i)
c[j]=1;
a[++a[0]]=i;
}
}
}
int putere(int baza, int exponent)
{
int rezultat=1;
while(exponent)
{
if(exponent%2==1)
{
exponent--;
rezultat=rezultat*baza;
}
exponent/=2;
baza=baza*baza;
}
return rezultat;
}
void invers_modular(int a, int b, int &x, int &y)
{
if(b!=0)
{
x=1;
y=0;
return;
}
int x1, y1;
invers_modular(b,a%b,x1,y1);
x=y1;
y=x1-(a/b)*y1;
}
int x, y;
int main()
{
freopen("ssnd.in", "r", stdin);
freopen("ssnd.out", "w", stdout);
formam_ciurul();
int n, x;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
float s=1;
scanf("%d", &x);
int nrdiv=1;
int sumasus=1;
int sumajos=1;
for(int d=1; a[d]<=x; d++)
if(x%a[d]==0)
{
int e=0;
while(x%a[d]==0)
{
e++;
x=x/a[d];
}
nrdiv=(nrdiv*(e+1));
sumasus=(sumasus*(putere(a[d],e+1)-1))%MOD;
sumajos=(sumajos*(a[d]-1))%MOD;
}
// invers_modular(sumajos, MOD, x, y);
// while(x<0)
// x+=MOD;
printf("%d %d \n", nrdiv, (sumasus/sumajos)%MOD);
}
return 0;
}