逆元
求解一(费马小定理)
ppp是一个质数,并且a%p≠0a \% p \not= 0a%p=0,则有ap−1≡1(modp)a ^ {p - 1} \equiv 1 \pmod pap−1≡1(modp),ap−2≡a−1a ^ {p - 2} \equiv a ^ {-1}ap−2≡a−1,即可得到逆元。
int quic_pow(int a, int n, int mod) {int ans = 1;while(n) {if(n & 1) ans = (ans * a) % mod;a = (a * a) % mod;n >>= 1;}return ans;
}
int inv(int a, int p) {return quick_pow(a, p - 2, p);
}
求解二(拓展欧几里德)
我们知道拓展欧几里德算法可以求解ax+by=gcd(a,b)ax + by = gcd(a, b)ax+by=gcd(a,b),对逆元考虑假设有a∗x+b∗y=1a * x + b * y = 1a∗x+b∗y=1那么显然有a∗x≡1(modb)a * x \equiv 1 \pmod ba∗x≡1(modb),这不就出来了吗,xxx就是aaa模bbb下的逆元,当然了这里也要有a,ba, ba,b互质。
int exgcd(int a, int b, int & x, int & y) {if(!b) {x = 1, y = 0;return a;}int gcd = exgcd(b, a % b, x, y);int temp = x;x = y;y = temp - a / b * y;return gcd;
}
int main() {int a, mod, inv, t;exgcd(a, mod, inv, t);return 0;
}
求解三(线性求解逆元)
我们假定有mod=k∗a+b,k=moda,b=mod%a,b<amod = k * a + b, k = \frac{mod} {a}, b = mod \% a,b < amod=k∗a+b,k=amod,b=mod%a,b<a
k∗a+b≡0(modmod)k * a + b \equiv 0 \pmod {mod}k∗a+b≡0(modmod)
同时乘以a−1b−1a ^ {-1}b^{-1}a−1b−1
得k∗b−1+a−1≡0(modmod)k * b ^{-1} + a ^{-1} \equiv 0 \pmod {mod}k∗b−1+a−1≡0(modmod)
a−1≡−k∗b−1(modmod)a ^{-1} \equiv -k * b ^ {-1} \pmod {mod}a−1≡−k∗b−1(modmod)
a−1≡mod∗b−1−k∗b−1(modmod)a ^ {-1} \equiv mod * b ^{-1} - k * b^ {-1} \pmod {mod}a−1≡mod∗b−1−k∗b−1(modmod)
所以我们就推导完了。
int inv[n], mod = 100007, n = mod;
inv[1] = 1;
for(int i = 2; i < n; i++) {inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
}
求解四(CnmC _{n} ^ {m}Cnm中的逆元求解)
a!−1=na! ^ {-1} = na!−1=n那么我们不难发现(a−1)!−1=a!−1∗a(a - 1) ! ^ {-1} = a! ^{-1} * a(a−1)!−1=a!−1∗a
void init() {fac[0] = 1;for(int i = 1; i < N; i++)fac[i] = (fac[i - 1] * i) % mod;inv[N - 1] = qpow(fac[N - 1], mod - 2);for(int i = N - 2; i >= 0; i--)inv[i] = (inv[i + 1] * (i + 1)) % mod;
}