zoukankan      html  css  js  c++  java
  • 【数论】同余问题

    定义

    两个整数a和b,除以一个大于1的自然数m所得余数相同,就称a和b对于模m同余或称a和b在模m下同余,即 a≡b(mod m)


    定律

    1. a≡a(mod d)
    2. a≡b(mod d)→b≡a(mod d)
    3. (a≡b(mod d),b≡c(mod d))→a≡c(mod d)

    如果a≡x(mod d),b≡m(mod d),则

    1. a+b≡x+m (mod d)
    2. a-b≡x-m (mod d)
    3. a*b≡x*m (mod d)

    值得一提的是:不满足a/n≡b/n(mod d) 求解用逆元

    费马小定理:

    如果b和p互质 则bp≡b(mod p)

    可用于:由此可得bp-1≡1(mod p) 结合求逆元方程b*x≡1(mod p) 得到bp-1≡b*x(mod p)

                  所以x≡bp-2(mod p)结合快速幂求出x


    扩展欧几里德

    已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a, b) =d

    void exgcd(int a,int b,int &d,int &x,int &y)
    {
        int t;
        if(b==0)//当b=0时 gcd(a,b)=a
                //因为1*a+0*0=a 所以ax+by=gcd(a,b)有一组解为
                //x=1 y=0 
        {
            d=a;
            x=1;
            y=0; 
        }
        else
        {
            exgcd(b,a%b,d,x,y);
            t=x;//推导得公式 
            x=y;
            y=t-(a/b)*y;
        }
    }
    View Code

    应用:

    求解ax+by=c 

    设g=gcd(a,b) a1=a/g   b1=b/g   c1=c/g

    用exgcd求a1*x1+b1*y1=1的整数解

    那么a1*g*c1*x1+b1*g*c1*y1=c1*g 即a*c1*x1+b*c1*y1=c

    所以x0=c1*x1   y0=c1*y1是一组解

    可推得通解为x=x0+b1*t   y=y0-a1*t   t属于Z

    PS:当gcd(a,b)不整除c的时候不满足上述过程


     

    线性同余方程 

    对于给定的整数a,b,m 求一个整数x满足a*x≡b(mod m) 或者给出无解

    方程可以改写成ax+my=b

    定理:

    1. a,b,m是整数且m>0 gcd(a,m)=d 如果d|b 则方程有d个mod m不同的解 否则无解
    2. 若gcd(a,m)=1 则称ax≡1(mod m)的一个解为a mod m的逆

    PS:对于特殊方程ax≡1(mod m) 当且仅当gcd(a,m)=1时才有解 可用Exgcd解

    例题:洛谷P1082:同余方程:https://www.luogu.org/problemnew/show/P1082

    代码:

    #include<iostream>
    using namespace std;
    int a,b,x,y;
    void exgcd(int a,int b,int &x,int &y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return;
        }
        exgcd(b,a%b,y,x);
        y-=a/b*x;
    }
    int main()
    {
        cin>>a>>b;
        exgcd(a,b,x,y);
        cout<<(x+b)%b;
    }
    View Code

    乘法逆元

     对于a/b mod p(b和p互质)

    First 费马小定理:

    如果b和p互质 且b<p 则bp≡b(mod p)

    由此可得bp-1≡1(mod p) 结合求逆元方程b*x≡1(mod p) 得到bp-1≡b*x(mod p)

    所以x≡bp-2(mod p)结合快速幂求出x

    #include<cstdio> 
    #define ll long long
    using namespace std;
    int n,p;
    inline ll ksm(ll a,ll b){
        ll ans=1;
        a%=p;
        while(b){
            if(b&1) ans=ans*a%p;
            a=a*a%p;
            b>>=1;
        }
        return ans%p;
    }
    void write(ll x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);putchar(x%10^48);
    }
    int main(){
        scanf("%d%d",&n,&p);
        for(int i=1;i<=n;i++)
            write(ksm(i,p-2)),putchar('
    ');
        return 0;
    }
    View Code

    Second 解不定方程:

    如果只是b和p互质则通过解同余方程

    解a*x≡1(mod p)等于解ax+py=1 

    因为p是质数 所以gcd(a,p)=1;

    即解ax+py=gcd(a,p) 用exgcd解x

    #include<cstdio>
    using namespace std;
    int x,y;
    void exgcd(int a,int b){
        if(!b){x=1,y=0;return ;}
        exgcd(b,a%b);
        int t=x;
        x=y,y=t-a/b*y;
    }
    void write(int x){
        if(x>9) write(x/10);
        putchar(x%10^48);
    }
    int main(){
        int n,p;
        scanf("%d%d",&n,&p);
        for(int i=1;i<=n;++i)
            exgcd(i,p),write((x%p+p)%p),putchar('
    ');
        return 0;
    }
    View Code

    Third 线性递推:

    #include<cstdio>
    #define ll long long
    using namespace std;
    const int maxn=3e6+5;
    ll inv[maxn]={0,1};
    int main(){
        int n,p;
        scanf("%d%d",&n,&p);
        printf("1
    ");
        for(int i=2;i<=n;i++)
            inv[i]=(ll)p-(p/i)*inv[p%i]%p,printf("%d
    ",inv[i]);
        return 0;
    }
    View Code

    中国剩余定理

    对于多个x≡ai(mod mi)

    M=∏ni=1mi    Mi=M/mi

    ti是线性同余方程Mi*ti≡1(mod mi)的一个解

    x=∑ni=1ai*Mi*ti

    int intchina(int n)
    {
        int Mi,x,y,d,ans=0;
        M=1;
        for(int i=1;i<=n;i++)
        M*=m[i];
        for(int i=1;i<=n;i++)
        {
            Mi=M/m[i];
            exgcd(Mi,m[i],d,x,y);
            ans=(ans+Mi*x*a[i])%M;
        }
        return (ans+M)%M;
    } 
    View Code
  • 相关阅读:
    php判断值是否为空
    MyQQ
    java动态定义二维数组问题
    回归CSDN
    字体工具栏
    传说中的服务器
    sql server 2000 出现不能执行查询,因为一些文件丢失或未注册
    chm文件打不开
    Cmd不能运行,窗口闪一下就消失
    isql病毒
  • 原文地址:https://www.cnblogs.com/BrokenString/p/9649312.html
Copyright © 2011-2022 走看看