求助大佬!!!为什么这份代码连样例都过不了?(推导和题解里第一篇差不多,主要的就是合并同余方程组)
#include<bits/stdc++.h>
using namespace std;
#define int long long
/*
推导: (此处同余符号写作==,等于号写作=)
n组同余方程:x==r[1] mod m[1]
x==r[2] mod m[2]
...
x==r[n] mod m[n]
考虑每次合并方程.
设要合并的方程为:x==a1 mod b1
x==a2 mod b2
分解成等式:x=k1b1+a1=k2b2+a2
后两项移项:k1b1+(-k2)b2=a2-a1
换元,令g=gcd(b1,b2),p1=b1/g,p2=b2/g
易证p1与p2互质,则将b1,b2代入:
m1=g*p1,m2=g*p2
得:
g*k1p1+g*(-k2)p2=a2-a1
两边同除以g:
k1p1+(-k2)p2=(a2-a1)/g
根据裴蜀定理,原方程(k1b1+(-k2)b2=a2-a1)有解当且仅当g|a2-a1 .
则现方程右式(a2-a1)/g为整数.
而左式中p1与p2互质,则可以先使用exgcd求出k1p1+(-k2)p2=1的解.
不妨设得到的某组解为t1,t2,即:
t1p1+(-t2)p2=1
方程两边同乘(a2-a1)/g,得:
t1(a2-a1)/g*p1+(-t2)(a2-a1)/g*p2=(a2-a1)/g
即k1和k2的一组解是:
k1=t1(a2-a1)/g,k2=(-t2)(a2-a1)/g
即得到x得一个解:x=a1+k1b1=a1+t1(a2-a1)/g*b1 .
根据某个定理,x得通解为x=x'+s*lcm(b1,b2) .
转化为同余方程:x==x'mod(lcm(b1,b2))
可以继续进行合并,推导结束.
*/
int n,r[1000005],m[100005],M;
int gcd(int x,int y){
while(x && y)(x>=y?x%=y:y%=x);
return x+y;
}
int lcm(int x,int y){
return x/gcd(x,y)*y;
}
void EXgcd(int a,int b,int &x,int &y){
if(!b)x=1,y=0;
else EXgcd(b,a%b,y,x),y=a/b*x;
return ;
}
void EXcrt(int num){
M=lcm(m[num],m[num+1]);
int a1=r[num],b1=m[num],a2=r[num+1],b2=m[num+1];
int g=gcd(b1,b2),p1=b1/g,p2=b2/g;
int t1,t2;EXgcd(p1,p2,t1,t2);
r[num+1]=(a1+t1*(a2-a1)/g*b1)%M,m[num+1]=M;
return ;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=0;i<n;i++)cin>>m[i]>>r[i];
for(int i=0;i<n-1;i++)EXcrt(i);
cout<<r[n-1]%m[n-1];
return 0;
}