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
  • 相关阅读:
    看雪-课程-加密与解密基础
    Windows API-Wininet&WinHTTP
    OS-Windows-bat-不等待当前命令返回继续执行后续指令
    Code-OPC DA- OPC Client Code Demo
    OS-Windows-Close Windows Error Reporting
    C-长度修饰符
    Code-Linux-time_t
    Windows-bat-Path
    Code-C++-CTime&ColeDateTime
    c++命名规范、代码规范和参数设置
  • 原文地址:https://www.cnblogs.com/MingSD/p/8416859.html
Copyright © 2011-2022 走看看