前言
今天的比赛第一题就是解线性同余方程,大概思路是有了,就是在求非质数模的时候卡住了。这时我才开始后悔之前没有好好学学扩展 gcd ,然后弱弱地打了个欧拉函数求逆元,结果还WA掉了QAQ。比赛完后赶紧恶补了一下。
算法功能
扩展欧几里得算法(
Extended Euclidean Algorithm
)是基于欧几里得而来解一类特殊的线性丢番图方程(
Diophantine equation
)的算法。
运用这个丢番图方程能有效解决许多数论问题。
算法解析
预备知识
欧几里得算法( gcd ),基本的解方程步骤。
算法步骤
和普通的欧几里得算法一样,扩展欧几里得算法先通过辗转相除法求得
gcd(A,B)
。
考虑在递归回退过程中,我们已经知道了
bx′+(a mod b)y′=gcd(A,B)
我们通过下列变形来得到方程
ax+by=gcd(A,B)
的解:
由此可得方程 ax+by=gcd(A,B) 的解为
如普通欧几里得算法,当 b=0 时, a=gcd(A,B) ,故这时返回方程解 x=1,y=0 即可(显然当 x,y 如刚才所述时, ax+by=gcd(A,B) )。然后像上述方法层层处理。
时间复杂度与普通欧几里得算法一样 O(logn2) 。
详细可见代码实现。
代码实现
void extended_gcd(int &a,int &b)
{
if (!b)
{
gcd=a;
a=1;
b=0;
return;
}
int a2=b,b2=a%b;
extended_gcd(a2,b2);
b=a2-(a/b)*b2;
a=b2;
}
算法用途
求解模意义下乘法逆元
显然,求
a
关于
然后 x 其实就是
这种求逆元算法比费马小定理求逆元运用范围更广,因为 p 不一定是质数,只用与
解不定方程
证明:对于不定方程 ax+by=c ,可以证明方程有整数解当且仅当 gcd(a,b)|c 。
由裴蜀定理,方程
ax+by=gcd(a,b)
一定存在整数解。
由于
gcd(a,b)|a,gcd(a,b)|b
,故
gcd(a,b)|(ax+by)
。
如果方程有实数解(在实数范围内成立),那么用
c
替换
证毕。
求其中一组解
前提条件:该不定方程存在整数解。
我们先求
ax′+by′=gcd(a,b)
。
设
d=cgcd(a,b)
,那么
x=dx′,y=dy′
一定是该不定方程的一组整数解。