扩展欧几里得算法exgcd
扩展欧几里得算法(exgcd)
欧几里得算法:求gcd。\(\gcd(x,y)=\gcd(y,x \mod y)\)
Code:
void gcd(int x,int y){
if(y==0)return x;
else return gcd(y,x%y);
}
扩展欧几里得是用来计算如下方程 \(x,y\) 的解:\(ax+by=gcd(a,b)\)
由欧几里得算法可知:\(ax+by=\gcd(a,b)=\gcd(b,a \mod b)\) ,\(bx_1+(a \mod b)y_1=\gcd(b,a \mod b)\) 。
递归欧几里得后,假设已经算出 \(x_1,y_1\) 。由上式可以推出 \(ax+by=bx_1+(a \mod b)y_1\) 。
\(\displaystyle bx_1+(a \mod b)y_1 = bx_1+(a-b \cdot \lfloor \frac{a}{b} \rfloor)y_1 = a \cdot y_1+b(x_1-\lfloor \frac{a}{b} \rfloor y_1)\)
由此,可以算出当前的 \(\displaystyle x=y_1 \ ,y=x_1-\lfloor \frac{a}{b} \rfloor y_1\) 。
在做欧几里得算到 \(b=0\) 时,就可以直接给出当前的 \(x,y\) 。\(x=1\) ,\(y\) 随意,最好是 \(0\) 。
Code:
void exgcd(int &x,int &y,int a,int b){
if(b==0){
x=1,y=0;
return;
}
exgcd(x,y,b,a%b);
int tmp=x;
x=y;
y=tmp-(a/b)*y;
}
exgcd求乘法逆元
求逆元有两种方法。
一是用费马小定理,有 \(a^{p-2} \equiv a^{-1} \pmod{p}\) 。可以用快速幂求,但要求 \(p\) 是质数,且常数较大。
二是用 exgcd。要求 \(a^{-1} \equiv x \pmod{p}\) ,也就是 \(a \cdot x \equiv 1 \pmod{p}\),就是求 \(ax+py=1\) 的 \(x\) 。因为是求逆元,所以 \(\gcd(a,p)=1\) 。相当于求解 \(ax+py=\gcd(a,p)\) 。因为求出的 \(x\) 仅能满足等式,不一定在剩余系中,要处理。可以这么写:
x=(x%p+p)%p;

浙公网安备 33010602011771号