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 }

 

posted on 2013-04-11 14:57  行者1992  阅读(202)  评论(0编辑  收藏  举报