Hello Kiki (中国剩余定理模版)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3579
1 #include <iostream> 2 #include <algorithm> 3 4 typedef long long LL; 5 6 using namespace std; 7 8 9 10 11 LL ex_gcd(LL a,LL b,LL &x,LL &y){ 12 if (b == 0){ 13 x = 1; 14 y = 0; 15 return a; 16 } 17 LL gcd = ex_gcd(b,a%b,y,x); 18 y -= (a/b)*x; 19 return gcd; 20 } 21 22 LL inv(LL t,LL p){ // t 关于 p 的逆元 23 LL x,y,d; 24 d = ex_gcd(t,p,x,y); 25 if (d == 1){ 26 return (x%p+p)%p; 27 }else 28 return -1; 29 } 30 31 32 // n个方程: x = a[i](mod m[i]) (0<=i<n) 33 34 LL china(int n,LL *a,LL *m){ 35 LL M = 1,ret = 0; 36 for (int i=0;i<n;i++){ 37 M *= m[i]; 38 } 39 for (int i=0;i<n;i++){ 40 LL w = M/m[i]; 41 ret = (ret + inv(w,m[i]) * w * a[i]) % M; 42 } 43 return (ret + M) % M; 44 } 45 46 LL CRT(LL b[],LL n[],int num){ 47 bool flag = false; 48 LL n1 = n[0],n2,b1 = b[0],b2,bb,d,t,k,x,y; 49 for (int i=1;i<num;i++){ 50 n2 = n[i],b2 = b[i]; 51 bb = b2 - b1; 52 d = ex_gcd(n1,n2,x,y); 53 if (bb%d){ 54 flag = true; 55 break; 56 } 57 k = bb / d * x; 58 t = n2 / d; 59 if (t<0) 60 t = -t; 61 k = (k % t + t) % t; 62 b1 = b1 + n1 * k; 63 n1 = n1 / d * n2; 64 } 65 if (flag) 66 return -1; 67 if (b1 == 0){ 68 b1 = n1; 69 } 70 return b1; 71 } 72 73 74 int main(){ 75 int t,num; 76 LL b[55],n[55]; 77 scanf("%d",&t); 78 int cas = 1; 79 while (t--){ 80 scanf("%d",&num); 81 for (int i=0;i<num;i++){ 82 scanf("%lld",&n[i]); 83 } 84 for (int i=0;i<num;i++){ 85 scanf("%lld",&b[i]); 86 } 87 printf("Case %d: %lld\n",cas++,CRT(b,n,num)); 88 } 89 return 0; 90 }