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 }