zoukankan      html  css  js  c++  java
  • 中国剩余定理和拓展中国剩余定理

    拓展和非拓展的中国剩余定理的区别在于同余方程组的mod是否两两互质,没有本质区别(个鬼)。

    首先用拓展中国剩余定理是完全可以ac中国剩余定理的板题的,但是性能上会差很多,不过应该不会卡这个常数的吧(大雾)

    中国剩余定理是很简单的,用拓展欧几里得的板子,加上下面的原理:

    很容易出代码,在这里不写了,您可以参见我的一篇叫《求逆元》的博客,里面有详细的介绍。下面讲讲拓展中国剩余定理的原理,证明很简单但是很长,所以只放一个引理。

    然后我们就可以把两个方程化成一个。方程越化越少,最后化成一个的时候就胜利了。

    出一个拓展中国剩余定理的板子。

     1 #include<bits/stdc++.h>
     2 #define ll long long 
     3 #define scan(i) scanf("%lld",&i)
     4 using namespace std;
     5 const int maxn=100010;
     6 int n;
     7 ll ai[maxn],bi[maxn];
     8 //mod放在bi里,余数放在ai里 
     9 ll mul(ll a,ll b,ll mod){
    10 //返回a*b%mod的值,怕爆long long来着 
    11     ll res=0;
    12     while(b>0)
    13     {
    14         if(b&1) res=(res+a)%mod;
    15         a=(a+a)%mod;
    16         b>>=1;
    17     }
    18     return res;
    19 }
    20 ll exgcd(ll a,ll b,ll &x,ll &y){
    21 //扩展欧几里得算法,运算结果返回ax+by=gcd(a,b)的特解,存储在x和y中,返回值是gcd(a,b) 
    22 //上述方程的特解为[x+b/gcd(a,b)t,y+a/gcd(a,b)t],t为任意整数 
    23     if(b==0)
    24     {
    25         x=1,y=0;
    26         return a;
    27     }
    28     ll ret=exgcd(b,a%b,y,x);
    29     y-=a/b*x;
    30     return ret;
    31 }
    32 ll excrt(){
    33 //有解出结果,无解出-1 
    34     ll x,y,k;
    35     ll M=bi[1],ans=ai[1];//第一个方程的解特判
    36     for(int i=2;i<=n;i++)
    37     {
    38         ll a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;//ax≡c(mod b)
    39         ll gcd=exgcd(a,b,x,y),bg=b/gcd;
    40         if(c%gcd!=0) return -1; //判断是否无解,然而这题其实不用
    41         x=mul(x,c/gcd,bg);
    42         ans+=x*M;//更新前k个方程组的答案
    43         M*=bg;//M为前k个m的lcm
    44         ans=(ans%M+M)%M;
    45     }
    46     return (ans%M+M)%M;
    47 }
    48 int main(){
    49     scan(n);
    50     for(int i=1;i<=n;++i)
    51     scan(bi[i]),scan(ai[i]);
    52     printf("%lld",excrt());
    53     return 0;
    54 }
  • 相关阅读:
    Codeforces Round #398 (Div. 2) B,C
    KMP模板
    HDU1711 KMP(模板题)
    HDU3265 线段树(扫描线)
    HDU2795 线段树
    HDU1828线段树(扫描线)
    HDU1832 二维线段树求最值(模板)
    HDU1698 线段树(区间更新区间查询)
    HDU3251 最大流(最小割)
    cf2.c
  • 原文地址:https://www.cnblogs.com/St-Lovaer/p/11761010.html
Copyright © 2011-2022 走看看