码迷,mamicode.com
首页 > 其他好文 > 详细

中国剩余定理模板+理解 推导

时间:2018-03-26 22:28:07      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:5*   post   剩余定理   turn   amp   ret   扩展欧几里得   htm   style   

此处省略引经据典。

(为了方便叙述,x=(a1,a2,a3)(b1,b2,b3)表示  x≡a1(mod b1)  x≡a2(mod b2) x≡a3(mod b3) )

举个栗子。

栗子 求x=(2,3,2)(3,5,7)的最小正整数解。

考虑转化为三个子问题。

思考后可得 x=(2*(1,0,0)(3,5,7)+3*(0,1,0)(3,5,7)+2*(0,0,1)(3,5,7))(mod 3*5*7)

(显然,对于互质的u,v,可以得到x=(0,0)(u,v)=u*v。因此,(1,0,0)(3,5,7)=(1,0)(3,35)=3-1(mod 5*7))

 

推而广之,考虑n个两两互质的数 m1,m2,m3,……mn-1,mn,设他们的积为M。

则,x=(a1,a2,a3,……an)(m1,m2,m3,……mn)=(a1*(1,0,……,0)+a2*(0,1,0,……,0)+……an*(0……0,1))=(a1*m1-1(modM/m1)+……an*mn-1(modM/mn))

而关于逆元,可以也只可以用扩展欧几里得来求(扩展欧几里得求逆元可以参考小蒟蒻的这篇博客)。

细节见代码。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int sz=1e5+5;
 4 int n,a[sz],m[sz],M,x,y,ans;
 5 void exgcd(int a,int b,int &x,int &y){
 6     if(b==0){
 7         x=0;
 8         y=1;
 9         return ;
10     }
11     exgcd(b,a%b,y,x);
12     y-=x*(a/b);
13 }
14 int main(){
15     scanf("%d",&n);
16     M=1;
17     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
18     for(int i=1;i<=n;i++)scanf("%d",&m[i]),M*=m[i];
19     for(int i=1;i<=n;i++){
20         exgcd(m[i],M/m[i],x,y);
21         ans+=a[i]*x;
22         ans=(ans%M+M)%M;
23     }
24     printf("%d",ans);
25     return 0;
26 }

 

中国剩余定理模板+理解 推导

标签:5*   post   剩余定理   turn   amp   ret   扩展欧几里得   htm   style   

原文地址:https://www.cnblogs.com/BLeaves/p/8651995.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!