模板及讲解
欧几里得算法
求gcd(a, b),即a和b的最大公倍数
欧几里得算法:
int gcd(int a, int b)
{
if (b==0) return a;
gcd(b, a%b);
}
求
ax+by=gcd(a,b)
的解
x,y
扩展欧几里得算法:
已求出下一个状态一组解
x1,y1
使得
b⋅x1+(a%b)⋅y1=gcd(a,b)
由
a%b=a−⌊ab⌋⋅b
,得
b⋅x1+(a−⌊ab⌋⋅b)⋅y1=gcd(a,b)
b⋅x1+a⋅y1−b⋅y1⋅⌊ab⌋=gcd(a,b)
a⋅y1+b⋅(x1−y1⋅⌊ab⌋)=gcd(a,b)
对照
ax+by=gcd(a,b)
,可得
x=y1,y=x1−y1⋅⌊ab⌋
由欧几里得算法终止条件
a=gcd(a,b),b=0
得,
a∗1+b∗0=gcd(a,b)
所以x,y的边界值是
1,0
通解:
int egcd(int a, int b, int &x, int &y)
{
if (b==0)
{
x = 1;
y = 0;//边界值
return a;//求最大公倍数
}
int temp = x;
int ans = egcd(b,a%b,x,y);
x = y;
y = temp-y*a/b;//公式计算
return ans;
}
求不定方程
ax+by=c
的最小一组解
x,y
:
先求出
g=gcd(a,b)
如果
c%g≠0
,无解
否则,将不定方程两边同时除以
g
,得
此时
gcd(a1,b1)=1
,可用扩展欧几里得算法求出
a1x1+b1y1=1
的解
x1,y1
即
a1x+b1y=c1
的一组解为
x1⋅c1,y1⋅c1
求最小解可用一组特解模
b
即可得到
求a 关于 m 的乘法逆元
由同余性质得,
ax−1=ny
变形,得
ax−ny=1
,此时
gcd(a,n)
必须为
1
且只有唯一解, 否则无解
即可使用扩展欧几里得算法求解
中国剩余定理
设正整数
有整数解。并且在模 M=m1⋅m2⋅...⋅mk 下有唯一解,
解为
其中 Mi=Mmi,M−1i 是 Mi 模 mi 下的逆元
解法:先
O(n)
的时间求出
M
,然后求出
int crt(int n, int *a, int *m)
{
int ans = 0;
int M = 1;
for (int i=1;i<=n;i++) M *= m[i];
for (int i=1;i<=n;i++)
{
int Mi = M/m[i];
int x,y;
e_gcd(Mi, m[i], x, y);//求Mi的逆元x
ans = (ans + a[i]*Mi*x)%M;
}
return (ans+M)%M;
}
筛选法求质数
int vis[n];
int sx()
{
int m = sqrt(n+0.5);
ms(vis,0);
for (int i=2;i<=n;i++)
if (!vis[i]) for (int j=i*i;j<=n;j+=i) vis[j] = 1;
}
欧拉函数
给出n的唯一分解式 n=pa11pa22pa33...pakk , 求出 1,2,3...,n 中与n互素的数的个数
公式(容斥原理):
可变形为:
即可在 O(k) 的时间复杂度算出 φ(n)
不给出唯一分解式求
φ(n)
:
根据变形的公式,可以枚举所有小于
n√
的因子,然后之后把他”除干净”即可
int phi(int n)
{
int ans = n;//ans为最后的答案
int m = (int)sqrt(n+0.5);
for (int i=2;i<=m;i++) if (n%i==0)
{
ans = ans/i*(i-1);//ans初值为n,因为1-(1/p) = (p-1)/p,由变形后公式可得
while (n%i==0) n/=i;//除干净
}
if (n>1) ans = ans/n*(n-1);
return ans;
}
用筛选法在 O(nloglogn) 时间复杂度求1~n中所有数的欧拉phi函数值:
int phitable(int n, int* phi)
{
for (int i=2;i<=n;i++) phi[i] = 0;
phi[1] = 1;
for (int i=2;i<=n;i++) if (!phi[i])
for (int j=i;j<=n;j+=i)
{
if (!phi[j]) phi[j] = j;
phi[j] = phi[j]/i*(i-1);
}
}
求正约数的个数
给出n的唯一分解式
n=pa11pa22pa33...pakk
, 求出
n
的正约数的个数
根据乘法原理,
快速幂
int fastpow(int a,int b)
{
int ans=1,base=a;
while(b!=0){
if(b&1!=0)
ans*=base;
base*=base;
b>>=1;
}
return ans;
}
排列
一般地,从
n
个不同元素中取出
(约定
0!=1
)
1 无重排列
从
n
个不同元素中有序且不重复取出
2 全排列
(1) 无重
当k-排列中的 k=n 时
3 重复排列
从
n
个不同元素中有序且可重复取出
重复排列个数为
4 圆周排列
从
n
个不同元素中无重复地取出
圆周排列个数为
组合
一般地,从
n
个不同元素中取出
(约定
0!=1
)
1 无重组合
从
n
个不同元素中无序且不重复取出
2 重复组合
从
n
个不同元素中无序但可重复取出
重复组合个数为
概率
1 数学期望
随机变量
X
的数学期望