zoukankan      html  css  js  c++  java
  • [数论]拓展中国剩余定理

    拓展中国剩余定理

    •拓展中国剩余定理

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

    $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
  • 相关阅读:
    8.18 二讲背包问题之完全背包
    8.18 动态规划——背包问题之01背包
    8.17 动态规划——书的抄写
    7.25 二分查找模板
    7.19 股票问题
    7.12 枚举-Jam的计数法
    7.12 递归——双色hanoi塔问题
    7.11 NOIP2007普及组第3题 守望者的逃离
    高数之泰勒公式
    数据结构_线性表之链表(1)
  • 原文地址:https://www.cnblogs.com/MMMinoz/p/11385728.html
Copyright © 2011-2022 走看看