中国剩余定理

 

 

中国剩余定理不互质情况下

POJ-2891

参考博客:http://yzmduncan.iteye.com/blog/1323599/

               https://www.cnblogs.com/linyujun/p/5199415.html

中国剩余定理不互质的情况下就是相当于把某个表达式通过另外的表达式表达出来

 假设我们现有2个表达式

X = a1 (mod m1)

X = a2 (mod m2)

等于 X = a1 + k1 * m1  = a2 + k2 * m2;

然后可以通过移项可以得到  k1 * m1 - k2 * m2 = a2 - a1  (1)

通过拓展欧几里得 我们可以知道 若此方程有整数解 必满足 (a2-a1)%gcd(m1,m2) == 0

(1)式可以变换成 k1*m1 = a2 - a1 (mod m2)

设 d = gcd(m1, m2), c = a2-a1

(m1/d) * k1 = c/d (mod m2/d)

k1 = c/d * inv(m1/d)  (mod m2/d)

设 K = c/d * inv(m1/d) 

k1 = k + y * (m2/d)

再将k1 带入 X = a1 + k1 * m1 可以得到

X =  a1 + k*m1 + y*(m1*m2/d)

即 X = a3 (mod m3)    (其中 a3 = a1 + k*m1  m3 = m1*m2/d)

然后通过这个式子对剩下的表达式进行整合 就可以求得最后的答案。

 1 #include<cstdio>  
 2 #define ll long long  
 3 using namespace std;  
 4 const int N = 100000+5;  
 5 ll M[N], A[N];// M->mod  A -> 余数  
 6 ll gcd(ll a, ll b) {  
 7     return b == 0 ? a : gcd(b, a%b);  
 8 }  
 9 void ex_gcd(ll a, ll b, ll &x, ll &y, ll &d)  
10 {  
11     if(b == 0) {  
12         x = 1, y = 0, d = a;  
13         return ;  
14     }  
15     ex_gcd(b, a%b, y, x, d);  
16     y -= a/b*x;  
17     return ;  
18 }  
19 ll inv(ll n, ll p) {  
20     ll x, y, d;  
21     ex_gcd(n, p, x, y, d);  
22     return (d == 1) ? (x % p + p) % p : -1;  
23 }  
24 ll china_(ll A[], ll M[], ll n)  
25 {  
26     ll x = A[0], m = M[0];  
27     for(int i = 1; i < n; i++) {  
28         ll c = A[i] - x, d = gcd(M[i], m);  
29         if(c % d) return -1;  
30         ll k = c/d * inv(m/d, M[i]/d)%(M[i]/d);  
31         x += m*k;  
32         m *= M[i]/d;  
33     }  
34     return (x%m+m)%m;  
35 }  
36 int main()  
37 {  
38     int n;  
39     while(~scanf("%d", &n)) {  
40         for(int i = 0; i < n; i++)  
41             scanf("%lld%lld", &M[i], &A[i]);  
42         ll ans = china_(A, M, n);  
43         printf("%lld", ans);  
44     }  
45     return 0;  
46 }  
View Code

 

posted @ 2018-02-05 11:32  Schenker  阅读(244)  评论(0编辑  收藏  举报