首页 > 其他 > 详细

中国剩余定理

时间:2019-05-30 00:27:28      阅读:181      评论:0      收藏:0      [点我收藏+]

中国剩余定理:
中国剩余定理(孙子定理)是用于解决一次同余方程组的一种方法。
定理的思路是将两个同余方程合为一个再下一个方程合并,最后得到答案。

那么先来看看对于两个方程的合并:

x = a1(mod n1)
x = a2(mod n2)

将方程都转换为乘积与和的形式:

x = n1 * T1+a1
x = n2 * T2+a2

将上述两式合并整理得:

n1T1=(a2-a1)+n2T2

设gcd(n1,n2) = d,c = a2 - a1,则合并的同余方程可变形为

(n1/d)*T1 = (c/d)(mod n2/d)

T1 =(c/d)*(n1/d)^-1(mod n2/d)

不妨设S = (c/d)(n1/d)^-1,则T1=t(n2/d) + S,那么

x = n1[t*(n2/d)+S]+a1 = (n1n2/d) t + n1S+a1,即x = n1S+a1(mod n1*n2/d)

那么在带入求解时新的a3 = n1S + a1,n3 = n1n2/d,最终,其中最小的x就是最后剩余的方程的a(mod n)

#include"iostream"
using namespace std;
typedef long long LL;
LL r[1001],m[1001],N; 
LL gcd(LL a,LL b){
    return b?gcd(b,a%b):a;
}
LL ex_gcd(LL a,LL b,LL &x,LL &y){
    if(b == 0){
        x = 1;
        y = 0;
        return a;
    }
    LL d = ex_gcd(b,a%b,x,y);
    LL t = x;
    x = y;
    y = t -(a/b)*y;
    return d;
    
}
LL Inv(LL a,LL b){
    LL d = gcd(a,b);
    if(d!=1)return -1;
    LL x,y;
    ex_gcd(a,b,x,y);
    return (x%b+b)%b;
}
bool megre(LL r1,LL m1,LL r2,LL m2,LL &r3,LL &m3){
    LL d = gcd(m1,m2);
    LL r = r2-r1;
    if(r%d)return 0;
    r = (r%m2+m2)%m2;
    m1/=d;m2/=d;r/=d;
    r*=Inv(m1,m2);
    
    r%=m2;r*=m1*d;r+=r1;
    
    m3 = m1*m2*d;
    
    r3 = (r%m3+m3)%m3;
    return 1;
    
}
LL CRT(){
    LL A1 = r[1],B1 = m[1];
    for(int i = 2;i <= N;i++){
     LL A2 = r[i],B2 = m[i];
     LL A3,B3;
     if(!megre(A1,B1,A2,B2,A3,B3))return -1;
     A1 = A3;
     B1 = B3;   
    }
    return (A1%B1+B1)%B1;
}
int main(){
     cin >> N;
     for(int i = 1;i <= N;i++)
     cin >> m[i];
     for(int i = 1;i<= N;i++)
     cin >> r[i]; 
     cout <<CRT();
    return 0;
}

中国剩余定理

原文:https://www.cnblogs.com/PHKCOOL/p/10946602.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!