zoukankan      html  css  js  c++  java
  • 中国剩余定理

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

    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
  • 相关阅读:
    ROS探索总结(三十一)——ros_control
    ROS探索总结(四十二)——twist_mux多路切换器
    综合面试十大维度解析
    面试官实战-2-业务面试官必须掌握的面试方法及实战演练
    面试官实战-1-素质测评起源和分析
    好的招聘官
    好的候选人
    专题工作模板
    月周报模板
    学习记录模板
  • 原文地址:https://www.cnblogs.com/MingSD/p/8416859.html
Copyright © 2011-2022 走看看