pij2891 扩展欧几里得中国剩余定理
代码思想来自scturtle's 渣代码集散地,转载请注明出处
不互质的中国剩余定理:利用扩展欧几里得定理将方程两两合并求解
假设C ≡ A1 (mod B1),C ≡ A2 (mod B2)。令C = A1 + X1B,那么X1B1 ≡ A2 − A1 (mod B2)。用扩展欧几里德算法求出X1,也就求出C。令B = lcm(B1, B2),那么上面两条方程就可以被C’ ≡ C (mod B)代替。迭代直到只剩下一条方程。你可以理解为新的答案C'即要mod B1,又要mod B2,所以就mod lcm(B1, B2)。而余数C 是刚前面求得的答案,也就是说C'不管怎么折腾,都还会保留一个C,即不会破坏前面的成果!
代码如下:
1 /*
2 参考别人的代码,欧几里得中国剩余定理
3 */
4
5 #include <stdio.h>
6 #include <iostream>
7 #include <string.h>
8 using namespace std;
9 long long ax,by;
10 long long ex_gcd(long long a,long long b)
11 {
12 if(b==0)
13 {
14 ax=1;
15 by=0;
16 return a;
17 }
18 long long gcd=ex_gcd(b,a%b);
19 long long temp=ax;
20 ax=by;
21 by=temp-a/b*by;
22 return gcd;
23 }
24 int main()
25 {
26 int t;
27 while(cin>>t)
28 {
29 long long m1,r1,m2,r2,gcd;
30 cin>>m1>>r1;
31 int flag=0;
32 for(int i=0;i<t-1;i++)
33 {
34
35 cin>>m2>>r2;
36 if(flag)
37 continue;
38 gcd=ex_gcd(m1,m2);
39 long long c=r2-r1;
40 if(c%gcd)
41 {
42 flag=1;
43 continue;
44 }
45 long long t=m2/gcd;
46 ax=ax*c/gcd;
47 ax=(ax%t+t)%t;
48 r1=m1*ax+r1;
49 m1=m2/gcd*m1;
50 }
51 if(flag)
52 printf("-1\n");
53 else
54 cout<<r1<<endl;
55 }
56 return 0;
57 }