中国剩余定理模板

互质 情况:

 1 #include <cstdio>//互质
 2 int exGcd(int a,int b,int &x,int &y)
 3 {
 4     if(b == 0)
 5     {
 6         x = 1,y = 0;
 7         return a;
 8     }
 9     int d = exGcd(b,a%b,y,x);
10     y -= a/b*x;
11     return d;
12 }
13 int Chinese_Remainder(int mod[],int prime[],int len)
14 {
15     int i,d,x,y,m,n,ret;
16     ret = 0,n = 1;
17     for(i=0; i<len; i++) n *= prime[i];
18     for(i=0; i<len; i++)
19     {
20         m = n/prime[i];
21         d = exGcd(prime[i],m,x,y);
22         ret = (ret+y*m*mod[i])%n;
23     }
24     return (n+ret%n)%n;
25 }
26 int main()
27 {
28     int n,i;
29     int mod[15],prime[15];
30     while(scanf("%d",&n)&&n)
31     {
32         for(i=0; i<n; i++)
33             scanf("%d%d",&prime[i],&mod[i]);
34         printf("%d\n",Chinese_Remainder(mod,prime,n));
35     }
36     return 0;
37 }
View Code

不互质的情况:

 1 //niiick
 2 #include<iostream>
 3 #include<vector>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstring>
 7 #include<cstdio>
 8 using namespace std;
 9 typedef long long lt;
10 
11 lt read()
12 {
13     lt f=1,x=0;
14     char ss=getchar();
15     while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
16     while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
17     return f*x;
18 }
19 
20 const int maxn=100010;
21 int n;
22 lt ai[maxn],bi[maxn];
23 
24 lt mul(lt a,lt b,lt mod)
25 {
26     lt res=0;
27     while(b>0)
28     {
29         if(b&1) res=(res+a)%mod;
30         a=(a+a)%mod;
31         b>>=1;
32     }
33     return res;
34 }
35 
36 lt exgcd(lt a,lt b,lt &x,lt &y)
37 {
38     if(b==0){x=1;y=0;return a;}
39     lt gcd=exgcd(b,a%b,x,y);
40     lt tp=x;
41     x=y; y=tp-a/b*y;
42     return gcd;
43 }
44 
45 lt excrt()
46 {
47     lt x,y,k;
48     lt M=bi[1],ans=ai[1];//第一个方程的解特判
49     for(int i=2;i<=n;i++)
50     {
51         lt a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;//ax≡c(mod b)
52         lt gcd=exgcd(a,b,x,y),bg=b/gcd;
53         if(c%gcd!=0) return -1; //判断是否无解,然而这题其实不用
54         
55         x=mul(x,c/gcd,bg);
56         ans+=x*M;//更新前k个方程组的答案
57         M*=bg;//M为前k个m的lcm
58         ans=(ans%M+M)%M;
59     }
60     return (ans%M+M)%M;
61 }
62 
63 int main()
64 {
65     n=read();
66     for(int i=1;i<=n;++i)
67     bi[i]=read(),ai[i]=read();
68     printf("%lld",excrt());
69     return 0;
70 }
View Code

 

posted @ 2020-08-18 16:31  JamZF  阅读(166)  评论(0编辑  收藏  举报