P4777 【模板】扩展中国剩余定理(EXCRT)
P4777 【模板】扩展中国剩余定理(EXCRT)
题目描述
给定
提示
对于
请注意程序运行过程中进行乘法运算时结果可能有溢出的风险。
数据保证有解。
说句闲话:
非常好的数学题,使我的大脑旋转。
感觉梦回小学奥数了:有一堆苹果,,3个一组剩1个,5个一组剩3个......
Solution:
先膜亿膜我认为最好的题解,十分美味可口,适合我这样的蒟蒻。
我们先转换一下原方程:
然后我们就可以用 exgcd 求出
然后记
回代:
然后
所以有:
然后这两个方程就被合并为了:
至于最后的答案统计嘛:
在最后一次 merge 做完之后,
所以有:
那么我们只需要在保证
然后这题就愉快的做完了。
Code:
#include<bits/stdc++.h> #define ll __int128 using namespace std; ll read() { ll res=0;char c; while(c<'0'||'9'<c)c=getchar(); while('0'<=c&&c<='9'){res=res*10+c-'0';c=getchar();} return res; } void exgcd(ll &x,ll &y,ll a,ll b) { if(!b)x=1,y=0; else {exgcd(y,x,b,a%b);y-=a/b*x;} } ll gcd(ll x,ll y) { return y ? gcd(y,x%y) : x; } ll lcm(ll x,ll y) { return x/gcd(x,y)*y; } ll a,b,A,B,x,y; void merge() { exgcd(x,y,a,A); ll d=gcd(a,A),mod=lcm(a,A),c=B-b,p=c/d,q=A/d; if(c%d){cout<<-1;exit(0);} x=x*p%q;x = x<0 ? x+q : x; b=(a*x+b)%mod;b = b<0 ? b+mod : b; a=mod; } int n; void work() { cin>>n; a=read(),b=read(); for(int i=2;i<=n;i++) { A=read(),B=read(); merge(); } long long ans=(long long )(b%a); cout<<ans; } int main() { //freopen("excrt.in","r",stdin);freopen("excrt.out","w",stdout); work(); return 0; }