【基础向】mx 不会数论 /kel
注:本文按 MX 主观顺序排列
基础
()
快速幂
int qp(int a,int b){
long long ans=1,base=a;
while(b>0){
if(b&1)(ans*=base)%=p;
(base*=base)%=p;
b>>=1;
}
return ans%p;
}
质数
单质数判断
试除法
找 \(2\) ~ \(\sqrt{n}\) 之间有没有可以被 \(n\) 整除的,暴力枚举。
tips:从小到大枚举,不然会 TLE。
多质数判断
埃氏筛
for(int i=2;i<=n;i++){
if(pri[i])continue;
res[++cnt]=i;
for(int j=2;i*j<=n;j++)pri[j*i]=1;
}
时间复杂度为 \(O(n \log^2n)\)。
优化: \(j=2\) 改成 \(j=i\),因为那些小于 \(i\) 的倍数枚举,都一定在 \(i\) 之前被遍历过。
欧拉筛
for(int i=2;i<=n;i++){
if(!pr[i])prs[++cnt]=i;
for(int j=1;j<=cnt&&i*prs[j]<=n;j++){
pr[i*prs[j]]=1;
if(i% prs[j]==0)break;
}
}
原理:保证了每一个合数只被其最小的质因子遍历,所以时间复杂度为 \(O(n)\)。
证明(by 乐宝/qq):
因为当我们发现了 \(i=k\times pri[j]\) 时,我们在用 \(i\) 和 \(pri[j+1]\) 遍历区间时会重复。
因为 \(i=k\times pri[j]\),所以 \(i\times pri[j+1]=k\times pri[j]\times pri[j+1]\) 因为 \(pri\) 数组中的素数是单调递增的,所以这样会使得在后面遍历的时候 \(pri[j+1]\times i\) 被重复遍历。
线性筛
for(int i=2;i<=n;i++){
if(!v[i]){
pri[++cnt]=i;
v[i]=i;
}
for(int j=1;j<=cnt&&i*pri[j]<=n;j++){
if(pri[j]>v[i])break;
v[i*pri[j]]=pri[j];
}
}
本质:从大到小累计质因子。
每个合数 \(i\times p\) 只会被它的最小质因子 \(p\) 筛一次,所以时间复杂度为 \(O(n)\)。
算术基本定理
任何一个大于 \(1\) 的正整数都能唯一的分解为有限个质数的乘积,即 \(N=p_1^{c_1}p_2^{c_2}...p_m^{c_m}\)
其中。\(c_i\) 都是正整数,\(p_i\) 都是质数。
试除法
注意最后要有 if(n>1)p[++cnt]=n,c[cnt]=1;

浙公网安备 33010602011771号