扩展欧几里得 【记录】

原始的欧几里得算法只能求解gcd(a, b),有两种写法

迭代写法:

LL gcd(LL a, LL b)
{
    LL t;
    while(b)
    {
        t = b;
        b = a%b;
        a = t;
    }
    return a;
}

递归写法:

LL gcd(LL a, LL b){
    return b == 0 ? a : gcd(b, a%b);
}




扩展欧几里得算法应用:

定理一:如果d = gcd(a, b),则必能找到正的或负的整数k和l,使d = a*x+ b*y。


定理二:若gcd(a, b) = 1,则方程ax ≡ c (mod b)在[0, b-1]上有唯一解。


定理三:若gcd(a, b) = d,则方程ax ≡ c (mod b)在[0, b/d - 1]上有唯一解。


对a*x + b*y = gcd(a, b) = d,求解gcd(a, b),x和y。 

求出的x和y可能是负数或0,但是|x| + |y|最小。

扩展后,可以求解a*x + b*y = c中的x和y,其中c % d == 0才有解。


代码:


//求解ax + by = gcd(a, b) = d,可以求出x和y。
//x和y可能是负数或者0 且求出的|x| + |y|最小
void gcd(LL a, LL b, LL &d, LL &x, LL &y)
{
    if(!b)
    {
        d = a;
        x = 1;
        y = 0;
    }
    else
    {
        gcd(b, a%b, d, y, x); 
        y -= x * (a / b);
    }
}

计算模n下a的逆元,不存在返回-1。


LL inv(LL a, LL n)//计算%n下 a的逆。如果不存在逆return -1;  
{ 
    LL d, x, y;  
    extend_gcd(a, n, d, x, y);  
    return d == 1 ? (x + n) % n : -1;  
}  


注意:

若 a == b (mod n) 能推出下面2条等式
1:(a+c) == b+c (mod n)
2:ac == bc (mod n) (但 ac == bc(mod n) 不能推出 a == b(mod n))


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值