[数论]拓展中国剩余定理

拓展中国剩余定理

•拓展中国剩余定理

拓展中国剩余定理是用来解同余方程

$egin{cases}xequiv c_{1}left( mod m_{1} ight) \ xequiv c_{2}left( mod m_{2} ight) \ ldots \ xequiv c_nleft( mod m_n ight) end{cases}$

ps.如果m1,m2,m3...mn两两互素的话,可以用中国剩余定理来求

•过程

假设

$xequiv c_{1} (mod m_{1})$  ①

$xequiv c_{1} (mod m_{2})$  ②

$x=c_{1}+m_{1}k_{1}$  ③

$x=c_{2}+m_{1}k_{2}$  ④

③=④得  $m_{1}k_{1}=c_{2}-c_{1}+m_{2}k_{2}$  ⑤

设$t=gcd(m1,m2)$

⑤ 两边同时除以t 得

$frac{m_{1}k_{1}}{t}=frac{c_{2}-c_{1}}{t}+frac{m_{2}k_{2}}{t}$ ⑥

⑥ $mod   frac{m_{2}}{t}$得

$k_{1}frac{m_{1}}{t}equiv frac{c_{2}-c_{1}}{t}(mod   frac{m_{2}}{t})$ ⑦

则$k_{1}=inv(frac{m_{1}}{t},frac{m_{2}}{t})cdot frac{c_{2}-c_{1}}{t}+frac{m_{2}}{t}cdot y$⑧

将⑧代入①

$x=inv(frac{m_{1}}{t},frac{m_{2}}{t})cdot frac{c_{2}-c_{1}}{t}cdot m_{1}+frac{m_{1}m_{2}}{t}y+c_{1}$

则$xequiv inv(frac{m_{1}}{t},frac{m_{2}}{t})cdot frac{c_{2}-c_{1}}{t}cdot m_{1}+c_{1}(mod frac{m_{1}m_{2}}{t})$

可以看出,x的值与$frac{c_{2}-c_{1}}{t}$有关

所以,当$(c_{2}-c_{1})|gcd(m_{1},m_{2})$时,x有解

若化成 $xequiv c (mod m)$

则$m=frac{m_{1}m_{2}}{t}$

$c=inv(frac{m_{1}}{t},frac{m_{2}}{t})cdot frac{c_{2}-c_{1}}{t}$%$frac{m_{2}}{t}cdot m_{1}+c_{1}$

•结论

通过中国剩余定理可以把两个同余式转化成一个新的同余式式

那推广一下n个同余式合并,

两个同余式求解之后得到一个新的同余式

再把新的同余式和其他的联立

最终就可以求出满足条件的解

•模板

 1 #include<cstdio>
 2 using namespace std;
 3 typedef long long ll;
 4 ll n;
 5 ll a[100010],b[100010]; 
 6 ll mul(ll A,ll B,ll mod) //快速乘取余 模板
 7 {
 8     ll ans=0;
 9     while(B>0)
10       {
11         if(B & 1) ans=(ans+A%mod)%mod;
12         A=(A+A)%mod;
13         B>>=1;
14       }
15     return ans;
16 }
17 ll exgcd(ll A,ll B,ll &x,ll &y) //扩展欧几里得 模板
18 {
19     if(!B)
20     {
21         x=1,y=0;
22         return A;
23     }
24     ll d=exgcd(B,A%B,x,y);
25     ll tmp=x;
26     x=y , y=tmp-A/B*y;
27     return d;
28 }
29 ll lcm(ll A,ll B) //求最小公倍数
30 {
31     ll xxx,yyy;
32     ll g=exgcd(A,B,xxx,yyy);
33     return (A/g*B);
34 }
35 ll excrt() //重点:求解同余方程组
36 {
37     ll x,y;
38     ll M=b[1],ans=a[1]; //赋初值 
39     //M为前k-1个数的最小公倍数,ans为前k-1个方程的通解
40     for(int i=2;i<=n;i++)
41       {
42         ll A=M,B=b[i];
43         ll C=(a[i]-ans%B+B)%B; //代表同余方程 ax≡c(mod b) 中a,b,c
44             
45         ll g=exgcd(A,B,x,y);
46         //求得A,B的最大公约数,与同余方程ax≡gcd(a,b)(mod b)的解,
47             
48         if(C%g) return -1; //无解的情况
49             
50         x=mul(x,C/g,B); //求得x的值,x即t 
51         ans+=x*M;  //获得前k个方程的通解
52         M=lcm(M,B); //更改M的值
53         ans=(ans%M+M)%M;
54       }
55     return ans;
56 }
57 int main()
58 {
59     scanf("%lld",&n);
60     for(int i=1;i<=n;i++)
61       scanf("%lld%lld",&b[i],&a[i]);
62     ll ans=excrt();
63     printf("%lld",ans);
64 }
View Code
原文地址:https://www.cnblogs.com/MMMinoz/p/11385728.html