数学常用模板
快速幂
long long power(long long x,long long y,long long p) {
long long ans=1;
while(y) {
if(y&1)
ans=x*ans%p;
y>>=1;
x=x*x%p;
}
return ans%p;
}
线性筛素数
void get_prim() {
memset(bb,true,sizeof(bb));
for(int i=2; i<=n; i++) {
if(bb[i]) {
prim[++tot]=i;
bb[i]=false;
}
for(int j=1; j<=tot&&i*prim[j]<=n; j++) {
bb[i*prim[j]]=false;
if(i%prim[j]==0)
break;
}
}
}
扩展欧几里得
扩展欧几里得是用来解决形如\(ax+by=\gcd(a,b)\)的方程的解的。
由\(\gcd\)的性质,我们可以知道\(\gcd(a,b)=\gcd(b,a \% b)\)。
假设有\(x',y'\)满足:
因为\(a \%b = a-\lfloor \frac{a}{b} \rfloor \times b\)。
所以有:
所以我们只需要令\(ax+by=\gcd(a,b)\)中的\(x=y',y=x-\lfloor \frac{a}{b} \rfloor \times y'\)即可,递归求解。
代码:
void exgcd(ll a,ll b,ll &x,ll &y){//ax+by=gcd(a,b)
if(b==0){x=1;y=0;return ;}
exgcd(b,a%b,x,y);
int z=x;x=y,y=z-y*(a/b);
}
乘法逆元
\(\cdot\) 线性筛逆元
\(1\sim n\)中所有整数在模\(p\)意义下的乘法逆元。
我们已知\(f[1]=1\)
设\(p=k\times i+r,(1<r<i<p)\),也就是 \(k\) 是\(p/i\)的商,\(r\)是余数 。
再将这个式子放到\(\pmod p\)意义下就会得到:
然后乘上\(i^{-1}\),\(r^{-1}\)
就可以得到:
f[1]=1;
for(int i=2; i<=n; i++)
f[i]=(p-p/i)*f[p%i]%p;
\(\cdot\) 费马小定理
费马小定理内容:
假如\(p\)是质数,且\(\gcd(a,p)=1\),那么\(a^{p-1} \equiv 1 \pmod p\)
因为逆元的定义是
若\(a\times x\equiv 1 \pmod {b}\),且\(a\)与\(b\)互质,那么我们就能定义:\(x\)为\(a\)的逆元,记为\(a^{-1}\)
所以我们发现上述定义中的\(x\)在费马小定理中就是\(a^{p-2}\),所以我们直接快速幂求\(a^{p-2}\pmod p\)即可。
代码就不放了。
\(\cdot\) 扩展欧几里得
用扩欧求逆元就相当于求线性同余方程\(a\times x\equiv c\pmod b\)里\(c=1\)的情况,根据扩欧,
这个方程可以变形成\(a\times x + b\times y=1\),直接套扩欧模板求\(x\)即可。
矩阵乘法+矩阵快速幂
struct matrix{
long long a[111][111];
matrix(){
memset(a,0,sizeof(a));
}
matrix operator *(matrix A){
matrix C;
for(long long i=1;i<=n;i++)
for(long long j=1;j<=n;j++)
for(long long k=1;k<=n;k++)
C.a[i][j]=(C.a[i][j]+a[i][k]*A.a[k][j])%mod;
return C;
}
}A,F;
void ksm(ll k) {
while(k) {
if(k&1)
F=F*A;
A=A*A;
k>>=1;
}
}
\(\cdot\) 卡特兰数
递归公式1
\(f(n)=\sum^{n−1}_{i=0}f(i)∗f(n−i−1)\)
递归公式2
\(f(n)=\frac{f(n−1)∗(4∗n−2)}{n+1}\)
组合公式1
\(f(n)=\frac{C^n_{2n}}{n+1}\)
组合公式2,重要!重要!重要!
\(f(n)=C^n_{2n}−C^{n−1}_{2∗n}\)