模板及讲解
求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 ,得 a1x+b1y=c1
此时 gcd(a1,b1)=1 ,可用扩展欧几里得算法求出 a1x1+b1y1=1 的解 x1,y1
即 a1x+b1y=c1 的一组解为 x1⋅c1,y1⋅c1
求最小解可用一组特解模 b 即可得到
求a 关于 m 的乘法逆元
ax≡1(modn)
由同余性质得, ax−1=ny
变形,得 ax−ny=1 ,此时 gcd(a,n) 必须为 1 且只有唯一解, 否则无解
即可使用扩展欧几里得算法求解
设正整数 m1,m2,...,mk 两两互素,则同余方程组
解法:先 O(n) 的时间求出 M ,然后求出 Mi , 用扩展欧几里得算法求出 M−1i ,根据公式进行计算
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互素的数的个数
公式(容斥原理):
不给出唯一分解式求 φ(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 的正约数的个数
根据乘法原理, 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 个不同元素中取出 m(1≤m≤n) 个元素,按照一定的顺序排成一列,叫做从 n 个元素中取出 m 个元素的一个排列(顺序不同是不同的两种方案)
(约定 0!=1 )
1 无重排列
从 n 个不同元素中有序且不重复取出 k(1≤k≤n) 个元素,称为 n 个不同元素中取出 k 个元素的一个无重排序,简称k-排列,所有这样的排列个数记为 Akn
3 重复排列
从 n 个不同元素中有序且可重复取出 k(1≤k≤n) 个元素,称为 n 个不同元素中取出 m 个元素的一个无重排序,简称k-可重排列
重复排列个数为
4 圆周排列
从 n 个不同元素中无重复地取出 k(1≤k≤n) 个元素排在一个圆周上,称为 n 个不同元素的一个圆周排列,简称k-圆排列
圆周排列个数为
一般地,从 n 个不同元素中取出 m(1≤m≤n) 个元素组成一组,叫做从 n 个元素中取出 m 个元素的一个组合(顺序不同是相同的两种方案)
(约定 0!=1 )
1 无重组合
从 n 个不同元素中无序且不重复取出 k(1≤k≤n) 个元素,称为 n 个不同元素中取出 k 个元素的一个无重组合,简称k-组合,所有这样的排列个数记为 Ckn
2 重复组合
从 n 个不同元素中无序但可重复取出 k(1≤k≤n) 个元素,称为 n 个不同元素中取出 k 个元素的一个重复组合,简称k-可重组合
重复组合个数为
1 数学期望
随机变量 X 的数学期望 E(X) 就是所有可能值按照概率加权的和。