【算法笔记】一大堆的筛法
·前置芝士
·积性函数
·定义:对于任意互质的整数a和b有性质f(a×b)=f(a)×f(b)的数论函数
字面意思,就是以a×b形式呈现的函数
· (其他)完全积性函数:对于任意整数a和b有性质f(a×b)=f(a)×f(b)的数论函数
·举例:
φ(n) 欧拉函数,代表小于等于n的数中与n互质的数的数目
μ(n) 莫比乌斯函数,看n有无平方数因数
gcd(n,k) 最大公因数,k固定
d(n) 正因子数目
σ(n) 正因子之和
λ(n) 能整除n的质因子数
·更多看
积性函数百度百科
·性质:
1)将n表示为n=p_{1}^{a_{1}} \times p_{2}^{a_{2}} \times p_{3}^{a_{3}}...\times p_{k}^{a_{k}},则有f(n)=f(p_{1}^{a_{1}}) \times f(p_{2}^{a_{2}}) \times f(p_{3}^{a_{3}})...\times f(p_{k}^{a_{k}})
2)若f为积性函数且有f(p^{n})=f^{n}(p),则f为完全积性函数
·正文
·筛法合集
1)O(n\sqrt{ n}) 暴力筛法(n<=2e5)
一个一个判断是否有因数,然后筛,是最常用的方法(确信
有些时候复杂度相当小,还是很方便的
不放代码了
2)O(nlog_{2}n) 埃氏筛(n<=1e6)
第二个比较经典的写法,对于每一个数筛去它的倍数
均摊下来复杂度如上
3)O(n) 欧拉筛(n<=1e8,当然了空间会炸)
线性筛,在2)的基础上优化得到的东西
vis[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i])p[++cnt]=i;
for(int j=1;j<=cnt&&i*p[j]<=n;j++){
vis[i*p[j]]=1;
if(i%p[j]==0)break;
}
}
以上三种是非常常用的写法,我们一般用这些就可以搞大部分的题目了。
然而,毒瘤出题人常常会把数据范围出的非常阴间(不过会有一些特殊性质)。这时候我们就需要一些别的筛法了。
4)Min_25筛
O(\frac{n^{0.75}}{\log n}) 专用于求前缀和的筛法
快乐的东西。大致做法:
①对所有x=\lfloor\frac nd\rfloor筛出不超过x的所有质数的f值之和
②求解原问题,即所有x=\lfloor\frac nd\rfloor筛出不超过x的所有数的f值之和
例子:loj6235
#include<bits/stdc++.h>
using namespace std;
long long n,ans=0,f,pos[1000010],k=0,cnt=0,g[1000010];
int id(long long x){
if(x<=f)return x;
else return k-n/x+1;
}
int main(){
scanf("%lld",&n);
f=sqrt(n);
for(long long i=1;i<=n;i=pos[k]+1){
pos[++k]=n/(n/i);
g[k]=pos[k]-1;
}
for(int i=2;i<=f;i++)
if(g[i]!=g[i-1]){
cnt++;
for(int j=k;pos[j]>=1ll*i*i;j--)
g[j]-=(g[id(pos[j]/i)]-cnt+1);
}
printf("%lld\n",g[k]);
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步