noip临近,有点怕需要数学知识定理才能做的题
快速幂
用途
O ( log t ) O(\log t) O(logt)时间内求解 x t x^t xt
证明&过程
由于 x a ⋅ x b = x a + b x^a\cdot x^b=x^{a+b} xa⋅xb=xa+b,而且每个自然数 t t t都可以拆分为不超过 log 2 t \log_2t log2t个二次幂的和,即 t = ∑ i = 0 k i 2 i t=\sum_{i=0} k_i2^i t=∑i=0ki2i
则 x t = ∑ i = 0 x k i 2 i x^t=\sum_{i=0}x^{k_i2^i} xt=∑i=0xki2i
其中 k i k_i ki为 0 / 1 0/1 0/1, x 2 i x^{2^i} x2i可以递推求得
代码
int qpow(int A,int B){
int res(1);while(B){
if(B&1)res=1ll*res*A%p;
A=1ll*A*A%p,B>>=1;
}return res;
}
一些定理
- 威尔逊定理:对于任意质数 p p p,有 ( p − 1 ) ! ≡ p − 1 ( m o d p ) (p-1)!\equiv p-1\pmod p (p−1)!≡p−1(modp)
- 费马小定理:对于任意质数 p p p,有 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1\pmod p ap−1≡1(modp)
扩展欧几里得
用途
求解形似 p ⋅ a + q ⋅ b = gcd ( a , b ) p\cdot a+q\cdot b=\gcd(a,b) p⋅a+q⋅b=gcd(a,b) 方程的解
证明&过程
由于 gcd ( a , b ) = gcd ( b , a   m o d   b ) \gcd(a,b)=\gcd(b,a\bmod b) gcd(a,b)=gcd(b,amodb),则有
p ⋅ a + q ⋅ b = gcd ( a , b ) = gcd ( b , a   m o d   b ) = p ⋅ b + q ⋅ ( a − a b ⋅ b ) p\cdot a+q\cdot b=\gcd(a,b)=\gcd(b,a\bmod b)=p\cdot b+q\cdot (a-\frac ab\cdot b) p⋅a+q⋅b=gcd(a,b)=gcd(b,amodb)=p⋅b+q⋅(a−ba⋅b)
= q ⋅ a + ( p − a b ⋅ q ) ⋅ b =q\cdot a+(p-\frac ab\cdot q)\cdot b =q⋅a+(p−ba⋅q)⋅b
递归求解即可
代码
void exgcd(int a,int b,int&x,int&y){
if(!b){
x=1,y=0;return ;}
exgcd(b,a%b,x,y);
int tmp=x;x=y;y=tmp-a/b*y;
}
线性求逆元
用途
在 O ( n ) O(n) O(n)时间内求解区间 [ 1 , n ] [1,n] [1,n]中所有数的逆元
证明&过程
求 i i i 关于 p p p 的逆元
一般的对于 i = 1 i=1 i=1,有 i − 1 ≡ 1 ( m o d p ) i^{-1}\equiv 1\pmod p i−1≡1(modp)
对于 i > 1 i>1 i>1 的情况,设 p = k ⋅ i + r p=k\cdot i+r p=k⋅i+r
放在模意义下, k ⋅ i + r ≡ 0 ( m o d p ) k\cdot i+r\equiv 0\pmod p k⋅i+