[POJ 2891] Strange Way to Express Integers (扩展中国剩余定理)
题面
传送门:POJ
Solution
就是裸的扩展中国剩余定理嘛qwq
注意几点:一定要时时刻刻去膜取模,否则一定会爆long long,尤其是算出来的\(k_0\)
这里给出几组易锅数据:(第三组容易爆long long)
input:
4
18373 16147
8614 14948
8440 17480
22751 21618
6
19576 8109
18992 24177
9667 17726
16743 19533
16358 12524
8280 22731
4
9397 38490
22001 25094
33771 38852
19405 35943
output
13052907343337200
-1
78383942913636233
Code
//POJ2891 Strange Way to Express Integers
//Jan,14th,2019
//扩展中国剩余定理
#include<iostream>
#include<cstdio>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
long long exgcd(long long A,long long B,long long &x,long long &y)
{
if(B==0)
{
x=1,y=0;
return A;
}
long long t=exgcd(B,A%B,x,y),tx=x;
x=y;
y=tx-(A/B)*y;
return t;
}
long long lcm(long long A,long long B)
{
long long tx,ty;
return (A*B)/exgcd(A,B,tx,ty);
}
const int N=100000+1000;
long long r[N],p[N];
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
p[i]=read(),r[i]=read();
long long R=r[1],P=p[1];
bool OK=true;
for(int i=2;i<=n;i++)
{
long long x,y,gcd=exgcd(P,p[i],x,y);
if((r[i]-R)%gcd!=0)
{
OK=false;
break;
}
long long t_P=P,t=p[i]/gcd;
x*=(r[i]-R)/gcd,P=lcm(P,p[i]),x=(x%t+t)%t;
R=((t_P*x)%P+R)%P;
}
if(OK==true)
printf("%lld\n",(R%P+P)%P);
else
printf("-1\n");
}
return 0;
}
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。