zoukankan      html  css  js  c++  java
  • 裴属定理与拓展欧几里得算法

    目录

    目录地址

    上一篇

    下一篇


    裴属定理

    裴蜀定理(或贝祖定理)得名于法国数学家艾蒂安·裴蜀,其形式上可以表现为:

    对于 (forall a,bin Z_+) ,设 (d=gcd(a,b))

    则一定存在 (x,yin Z_+) 使得: (ax+by=d)

    证明:

    设存在 (x,yin Z_+) 使得 (ax+by=d) 成立

    (ax+by=gcd(a,b)=gcd(b,amod b)=gcd(b,a-(a/b)cdot b)) 得到

    (ax+by=bx'+[a-(a/b)cdot b]y'=ay'-b(x'-(a/b)cdot y'))

    因此得到:若 (b)(amod b) 存在解 (bx'+(amod b)y'=gcd(b,amod b)=d)

    则存在 (x,y)

    又因为将该过程视为递归,则递归的边界为 (a''=gcd(a,b),b''=0) 显然有解 (x''=1,y''=0)

    因此存在 (x,y)

    裴属定理的推论

    由于存在 (ax+by=gcd(a,b))

    故对 (forall kin Z_+) 都存在 (X,Yin Z_+) 使得 (aX+bY=kcdot gcd(a,b))

    证明:

    (x,yin Z_+) 使得 (ax+by=gcd(a,b))

    (X=kx,Y=ky) 得到 (aX+bY=akx+bky=k(ax+by)=kcdot gcd(a,b))

    裴属定理的推广形式

    存在 (x_{1dots n}in Z_+) 使得 (displaystyle sum_{i=1}^na_ix_i= ext{gcd}_{i=1}^n a_i)

    其中 ( ext{gcd}_{i=1}^n a_i) 表示 (a_{1dots n}) 的最大公因数

    证明: (n=2) 我们已经证明

    (n=k) 时成立, (d= ext{gcd}_{i=1}^k a_i)

    则存在 (x'_{1dots k}) 使得 (displaystyle sum_{i=1}^ka_ix'_i=d)

    由于存在 (c,x_{k+1}in Z_+) 使得 (cd+a_{k+1}x_{k+1}=gcd(d,a_{k+1}))

    (x_i=cx'_i,iin[1,k]igcap Z) 得到 (displaystyle sum_{i=1}^{k+1} a_ix_i=gcd(d,a_{k+1}))

    (c_i)(a_{1dots k})(i) 个因数的次数的最小值, (d_i)(a_{k+1}) 的第 (i) 个因数的次数 ,则 (displaystyle d=prod_{i=1}^mp_i^{c_i})

    因此 (displaystyle gcd(d,a_{k+1})=prod_{i=1}^mp_i^{min(c_i,d_i)}= ext{gcd}_{i=1}^{k+1} a_i)

    故原命题得证

    同时,我们也得到很重要的性质:

    ( ext{gcd}_{i=1}^n a_i=gcd( ext{gcd}_{i=1}^{n-1} a_i,a_n))


    拓展欧几里得算法

    由上面的方法,我们发现,实际上 (x,y) 是事实可求的值

    由递归过程:

    (egin{cases} a=b \ \ b=amod b \ \ x=y' \ \ y=x'-(a/b)cdot y' end{cases})

    递归边界为:

    (egin{cases} a \ \ b=0 \ \ x=1 \ \ y=0 end{cases})

    因此写出代码:

    int exgcd(int a,int b,int &x,int &y){
        if(b==0){
            x=1;
            y=0;
            return a;
        }
        int g=exgcd(b,a%b,x,y);
        int tmp=x;
        x=y;
        y=tmp-a/b*x;
        return g;
    }
    

    或者有人会发现,实际上递归式中的 (x,y) 可以理解为:

    (x,y) 交换,然后 (y-=(a/b)cdot x)

    因此非递归写为:

    int exgcd(int a,int b,int &x,int &y){
        int m=b,tmp[10000]={0},cur=1;
        x=1,y=0;
        tmp[0]=a/b;
        while(b^=a^=b^=a%=b) tmp[cur++]=a/b;
        while(cur--) y^=x^=y^=x-=tmp[cur]*y;
        return a;
    }
    
  • 相关阅读:
    JavaWeb servlet过滤器
    JavaWeb--jsp九大内置对象完整总结
    response.getWriter()和jsp中的out对象的区别
    JavaWeb基础(jsp初识)
    Oracle 存储过程的基本语法 及注意事项
    PLSQL编程基础 :分支、循环语句
    oracle数据库的高级查询方法 多表联合查询
    oracle中 SQL语句 经典练习题
    git 拉取远程分支报错(fatal: '' is not a commit and a branch '' cannot be created from it)
    根据端口号查询进程并杀掉被占用的进程
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/12388575.html
Copyright © 2011-2022 走看看