快速幂
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}
floor imes b)。
所以有:
所以我们只需要令(ax+by=gcd(a,b))中的(x=y',y=x-lfloor frac{a}{b}
floor imes 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) 线性筛逆元
(1sim n)中所有整数在模(p)意义下的乘法逆元。
我们已知(f[1]=1)
设(p=k imes 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 imes xequiv 1 pmod {b}),且(a)与(b)互质,那么我们就能定义:(x)为(a)的逆元,记为(a^{-1})
所以我们发现上述定义中的(x)在费马小定理中就是(a^{p-2}),所以我们直接快速幂求(a^{p-2}pmod p)即可。
代码就不放了。
(cdot) 扩展欧几里得
用扩欧求逆元就相当于求线性同余方程(a imes xequiv cpmod b)里(c=1)的情况,根据扩欧,
这个方程可以变形成(a imes x + b imes 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})