前置知识
写在前面
Q:啥叫扩展欧几里得啊
A:扩展欧几里得算法是用来在已知 (a, b) 求解一组 (x, y) ,使他们满足斐蜀等式: (ax + by = gcd(a, b) = d)
尝试搞一下它
先考虑一下比较简单的特殊情况,如果 (b = 0),那么 (gcd(a, b) = a),并显然存在一组解 (x = 1, y = 0)
对于一般情况,设 (ax + by = gcd(a, b)),
根据欧几里得算法, (gcd(a, b) = gcd(b, a mod b))
肯定存在式子 (bx_2 + (a mod b)y_2 = gcd(b, a mod b))
[ herefore ax_1 + by_1 = bx_2 + (a !!mod b)y_2
]
[egin{alignedat}{3}
ecause ax_1 + by_1 & = bx_2 + (a - a div b imes b)y_2 \
& = bx_2 + ay_2 - a div b imes b imes y_2 \
& = ay_2 + b(x_2 - a div b imes y_2)
end{alignedat}]
[ herefore x_1 = y_2 , y_1 = x_2 - a div b imes y_2
]
继续递推下去就好啦~
实现代码:
int exgcd(int a, int b, long long &x, long long &y)
{
if(b == 0) return x = 1, y = 0, a;
int d = exgcd(b, a % b, y, x);//d的值实际上就是gcd(a,b),如果不需要的话可以不求
return y -= a / b * x, d;
}
不过毕竟有扩欧这种帅气的名字,可不能只干这点活
它还可以求逆元:
设 (x) 为 (a) 在模 (p) 意义下的逆元,那么满足式子:
[ax equiv 1
]
那么有:
[ax + my = 1
]
然后用 (exgcd) 搞出 (x) 即可(这就是为啥 (a) 和 (m) 一定要互质才能使得 (a) 在模 (m) 意义下有逆元)
实现代码:
long long inv(long long a,long long m)
{
long long x,y;
long long d = exgcd(a, m, x, y);
return d == 1 ? (x + m) % m : -1 ;//不互质就没有逆元
}
(The) (end.)