gcd(a,b)=gcd(b,a%b)
证明:
设 a=bq+r=bq+a%b,
设 a%b=a−bq,
设 d=gcd(a,b),则 d∣a, d∣b→d∣a%b,
即 d=(b,a%b)。
得证
代码
int gcd(a,b) {
if(!b)return a;
return (b,a%b);
}
原理
裴蜀定理ax+by=gcd(a,b)
以及gcd(a,b)=gcd(b,a%b)
带入有ax1+by1=bx2+a%by2=bx2+(a−bq)y2
对比系数有x1=y2,y2=x2−bay2
注意到 a×x+0×y=gcd(a,0)=a,得 x=1, y=0。
void exgcd(a,b,int& x,int& y){
if(!b){
x=1,y=0;
return;
}
exgcd(b,a%b,y,x); // 求解 gcd(b,a%b)的系数y,x
// x=y_2 已经自动赋值了
y = y - a/b *x; // x_2 - a/b y_2
}
若 gcd(a,b)=1,且 b 为质数,则 x=a−1(modp)。
ap−1=1(modp)
即aap−2=1(modp)
得a−1=ap−2
inv[1]=1;
for(i in 1... ) {
inv[i]=(p-p/i)*inv[p%i] % p;
}
inv(i)=(p−p/i)inv(p%i)%p
inv(1)=1
我们需要证明 inv(i)=(p−p/i)⋅inv(p%i)%p。
设 inv(i) 是 i 在模 p 意义下的逆元,即 i⋅inv(i)≡1(modp)。
根据模运算的性质,有:
i⋅inv(i)≡1(modp)
我们可以将 i 表示为 p 和 p%i 的线性组合:
i=p−(p%i)⋅⌊ip⌋
设 inv(p%i) 是 p%i 在模 p 意义下的逆元,即:
(p%i)⋅inv(p%i)≡1(modp)
将 i 的表达式代入 i⋅inv(i)≡1(modp):
(p−(p%i)⋅⌊ip⌋)⋅inv(i)≡1(modp)
展开并整理:
p⋅inv(i)−(p%i)⋅⌊ip⌋⋅inv(i)≡1(modp)
由于 p⋅inv(i)≡0(modp),因此:
−(p%i)⋅⌊ip⌋⋅inv(i)≡1(modp)
两边同时乘以 −1:
(p%i)⋅⌊ip⌋⋅inv(i)≡−1(modp)
将 inv(p%i) 代入上式:
(p%i)⋅inv(p%i)≡1(modp)
因此:
⌊ip⌋⋅inv(i)≡inv(p%i)(modp)
所以:
inv(i)≡(p−p/i)⋅inv(p%i)(modp)
即:
inv(i)=(p−p/i)⋅inv(p%i)%p
得证。