数论之欧几里得与拓展欧几里得算法

知识储备:
1.“|”整除号
eg:若b可被a整除,或a整除b,则可记作a|b
如2|6,8|16
性质:
①a|b,b|c => a|c
②a|b,a|c => a|(b+c)=>a|(ma+mb) (m,n∈Z)
③a|b(a≠0) => |a|≤|b|

2.“≡”同余号
两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余
记作a≡b(mod m)
读作a同余于b模m,或读作a与b关于模m同余。
比如26≡14(mod 12)
设m是大于1的正整数,a,b是整数,如果m|(a-b),则称a与b关于模m同余,记作a≡b(mod m)

3.

一、欧几里得算法
欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数(gcd)。
基本算法:
设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b)
性质:
gcd( am a m -1, an a n -1) = agcd(m,n) a g c d ( m , n ) -1
推广:
若 gcd(a,b)=1
gcd( am a m - bm b m , an a n - bn b n ) = agcd(m,n) a g c d ( m , n ) - bgcd(m,n) b g c d ( m , n )
若gcd(a,b)=1
则 gcd(a+b,a)=1 gcd(a+b,b)=1 则 gcd(a+b,ab)=1

//代码实现
int gcd(int a,int b)
{
    if(a<b)
        swap(a,b);//优化加速
    return b==0?a:gcd(b,a%b);
}

二、拓展欧几里得
基本算法:
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数(可为负数)对 x,y ,使得 gcd(a,b)=ax+by。

这是一个不定方程(其实是一种丢番图方程),由于满足方程的解无穷多个,在实际的解题中一般都会去求解x或是y的最小正数的值。

这就用到了拓展欧几里得算法。

证明:设 a>b:
  1.显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
  2.ab!=0 时,设
  a x1 x 1 +b y1 y 1 =gcd(a,b);
  b x2 x 2 +(a mod b) y2 y 2 =gcd(b,a mod b);
  根据欧几里德原理gcd(a,b)=gcd(b,a mod b)
  则:a x1 x 1 +b y1 y 1 =b x2 x 2 +(a mod b) y2 y 2 ; ///a mod b =r
  即:a x1 x 1 +b y1 y 1 =b x2 x 2 +(a- ab a b b ) y2 y 2 =a y2 y 2 +b x2 x 2 - ab a b b y2 y 2 ;
  根据恒等定理(对应系数相等)得:
   x1 x 1 = y2 y 2 ;
   y1 y 1 = x2 x 2 - ab a b y2 y 2 ;
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。

//拓展欧几里得递归实现
int exgcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    int ans=exgcd(b,a%b,x,y);
    int temp=x;
    x=y;
    y=temp-a/b*y;
    return ans;//返回的是gcd(a,b)
}
//拓展欧几里得非递归实现
int exgcd(int m,int n,int &x,int &y)
{
    int x1,int y1,x0,y0;
    x0=1;
    y0=0;
    x1=0;
    y1=1;
    x=0;
    y=1;
    int ans=m%n;
    int q=(m-r)/n;
    while(ans)
    {
        x=x0-q*x1;
        y=y0-q*y1;
        x0=x1;
        y0=y1;
        x1=x;
        y1=y;
        m=n;
        n=ans;
        ans=m%n;
        q=(m-ans)/n;
    }
    return n;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值