中国剩余定理

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 using namespace std;
 5 typedef long long LL;
 6 // 求x和y使得ax+by=d并且|x|+|y|最小。其中d=gcd(a,b)
 7 void exgcd(LL a,LL b,LL& d,LL& x,LL& y){
 8     if(!b) d = a,x = 1,y = 0;
 9     else{
10         exgcd(b,a % b,d,y,x);
11         y -= x * (a / b);
12     }
13 }
14 // n个方程:x=a[i](mod m[i]) (0<=i<n)
15 LL china(int n,int* a,int* m){
16     LL M = 1,d,y,x = 0;
17     for(int i = 0 ; i < n ; i++) M *= m[i];
18     for(int i = 0 ; i < n ; i++){
19         LL w = M / m[i]; // i = j时 wi与mi互素
20         exgcd(m[i],w,d,d,y); // 找到pi和qi:wi*pi+mi*qi=1
21         x = (x + y * w * a[i]) % M; // 令ei=wi*pi
22     }
23     // 解为x=sum{ei*ai|i=0,1,...,n-1}
24     return (x + M) % M;
25 }
26 int main(){
27     int n = 3;
28     int a[] = {2,3,2};
29     int m[] = {3,5,7};
30     printf("%lld\n",china(n,a,m));
31     return 0;
32 }

 

posted @ 2016-08-25 17:39  Yan_Bin  阅读(150)  评论(0)    收藏  举报