Solution
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define PR 531169
int fakt[PR];
int inverz[PR];
int inv(int x)
{
int y=PR;
int p0=1,p1=0,t,p2;
while(y)
{
p2=p0-x/y*p1;
p0=p1;
p1=p2;
t=y;
y=x%y;
x=t;
}
p0%=PR;
if (p0<0)
return p0+PR;
return p0;
}
void racunajfakt()
{
int i;
long long temp=1;
fakt[0]=1;
inverz[0]=1;
for(i=1;i<PR;i++)
{
temp=(temp*i)%PR;
fakt[i]=temp;
inverz[i]=inv(temp);
}
}
long long malifakt(int x)
{
return fakt[x];
}
int faktost(int x)
{
if (x/PR%2==0)
return (malifakt(x%PR)*malifakt(x/PR)%PR);
else
return PR-(malifakt(x%PR)*malifakt(x/PR)%PR);
}
int ost(int x, int y)
{
long long temp;
if ((x+y)/PR>x/PR+y/PR)
return 0;
temp=fakt[(x+y)%PR];
temp=temp*fakt[(x+y)/PR]%PR;
temp=temp*inverz[x%PR]%PR;
temp=temp*inverz[y%PR]%PR;
temp=temp*inverz[x/PR]%PR;
temp=temp*inverz[y/PR]%PR;
return temp;
}
int gcd(int a, int b)
{
int c;
while (b)
{
c=b;
b=a%b;
a=c;
}
return a;
}
char x[32000];
int prosti[5000];
int koliko;
int elem[10];
int brElem;
int a,b;
int ukupno;
void rek(int zadnji, int mu, int prod)
{
int i;
ukupno+=mu*ost(a/prod,b/prod);
ukupno%=PR;
for(i=zadnji;i<brElem;i++)
rek(i+1,-mu,prod*elem[i]);
}
int main()
{
int t;
int i,j,temp;
for(i=2;i*i<32000;i++)
if (!x[i])
for(j=i*i;j<32000;j+=i)
x[j]=1;
for(i=2;i<32000;i++)
if (!x[i])
prosti[koliko++]=i;
racunajfakt();
scanf("%d",&t);
while(t--)
{
scanf("%d %d", &a, &b);
temp=gcd(a,b);
brElem=0;
for(i=0;prosti[i]*prosti[i]<=temp;i++)
if (temp%prosti[i]==0)
{
elem[brElem++]=prosti[i];
while (temp%prosti[i]==0)
temp/=prosti[i];
}
if (temp>1)
elem[brElem++]=temp;
ukupno=0;
rek(0,1,1);
if (ukupno<0)
ukupno+=PR;
printf("%d\n",ukupno);
}
return 0;
}
No comments:
Post a Comment