裴蜀定理
对于任意整数
证明:
在欧几里得算法的最后一步,即
若
由数学归纳法可知,裴蜀定理成立。
扩展欧几里得算法
由裴蜀定理的证明过程可得扩展欧几里得算法:
int exgcd(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
int d = exgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - y * (a / b);
return d;
}扩展欧几里得算法可求出
其中
明确了通解的形式,那么如何求
求解不定方程
扩展欧几里得算法求解不定方程的过程如下:
- 判断方程
是否有整数解。有解的充要条件是 。 - 使用扩展欧几里得算法求
的一组特解 。 - 在等式
的两边同时乘以 ,得到 。 - 对照
得到它的一个解为: - 设
,则 的通解可以表示为: 其中 为任意整数。
求解线性同余方程
给定整数
求逆元
若整数
int inv(int b, int m) {
int x, y;
exgcd(b, m, x, y);
return (x % m + m) % m;
}上述代码求解逆元的时间复杂度为
费马小定理求逆元
当
这里就可以使用快速幂求解
int inv(int b, int p) {
return qmi(b, p - 2, p)
}线性递推求逆元
当需要求
线性递推求解逆元的思路如下:
使用 inv[i] 表示 inv[i] = (p - p / i) * inv[p % i] % p。
证明:
当
两边同时乘上
移项得:
两边同时乘上
代入
具体代码如下:
int n, p, inv[N];
void init_inv(int n, int p) {
inv[1] = 1;
for (int i = 2; i <= n; i++) {
inv[i] = (p - p / i) * inv[p % i] % p;
}
}中国剩余定理
《孙子算经》中记载了这样一个问题:有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?使用现代语言描述即是求满足以下条件的整数:除以
即:
以上即是线性同余方程组。而《孙子算经》中记载的中国剩余定理就是解决形如以下形式的一次线性同余方程组的算法。
其中
求解过程如下:
- 计算所有模数的积
。 - 对于第
个方程: - 计算
。 - 计算
在模 意义下的逆元 。 - 计算
,注意不要取模。
- 计算
- 方程组在模
意义下的唯一解为: 。
int CRT(int k, int a[], int r[]) {
int M = 1, ans = 0;
for (int i = 1; i <= k; i++) M = M * r[i];
for (int i = 1; i <= k; i++) {
int b = M / r[i], inv_b, y;
exgcd(b, r[i], inv_b, y);
ans = (ans + a[i] * b * inv_b % M) % M;
}
return (ans % M + M) % M;
}