// 求 a * x = b (mod m) 的解ll modequ(ll a, ll b, ll m){
ll x, y;
ll d = exgcd(a, m, x, y);
if (b % d != 0) return-1;
m /= d; a /= d; b /= d;
x = x * b % m;
if (x < 0) x += m;
return x;
}
简化剩余系
所有的 n 满足 0<n≤m,(n,m)=1 构成了一个模 m 的简化剩余系。ϕ(m) 表示 n 的个数。
ll phi(ll n){
ll ans = n;
for (int i = 2; i*i <= n; i++) {
if (n % i == 0) {
ans = ans / i * (i - 1); //*(1-1/i)while (n % i == 0) n /= i;
}
}
if (n > 1) ans = ans / n * (n - 1); //还剩下就再乘return ans;
}
欧拉定理
若 (a,m)=1,则 aϕ(m)≡1(modm)
m为素数时有 费马小定理:ap−1≡1(modp)
欧拉定理证明
设 1−n 中与 n 互质的数为:p1,p2,...,pϕ(n),则有 ak1,ak2,...skϕ(n),二者在模n意义下等价(可以手搓几个例子模拟),
二式分别累乘,有 k1k2...kϕ(n)≡aϕ(n)k1k2...kϕ(n)(modn),即
ϕ(n)∏i=1ki≡aϕ(n)ϕ(n)∏i=1ki(modn)
根据同余公式三 ka≡ka′(modm)→a≡a′(modm(m,k))
则有
ϕ(n)∏i=1ki≡aϕ(n)ϕ(n)∏i=1ki(modn)→1≡aϕ(n)(modn)
逆元
ax≡1(modm),称 x 为 a 的逆元,记作 a−1
快速幂求逆元模板
素数:
ap−1≡1(modp)→aap−2≡1(modp)→ap−2≡a−1(modp)
ll qmi(ll a, ll k, ll p){
ll ans = 1;
while (k) {
if (k & 1) ans = ans * a % p;
k >>= 1;
a = a * a % p;
}
return ans;
}
//a mod p 的逆元为 qmi (a, p - 2, p)
扩展欧几里得求逆元模板
非素数:
aϕ(m)≡1(modm)→aϕ(m)−1≡a−1(modm)
int d = exgcd(a, p, x, y);
if (d == 1) cout << (1ll * x + p) % p << endl;
elseputs("impossible");