杜教筛学习笔记
1.笛卡尔树学习笔记2.基环树学习笔记3.后缀数组学习笔记4.虚树学习笔记5.网络流学习笔记6.线性基学习笔记7.拉格朗日插值学习笔记
8.杜教筛学习笔记
9.数论分块学习笔记10.莫比乌斯反演学习笔记11.广义后缀自动机学习笔记12.后缀自动机学习笔记13.回文自动机学习笔记14.Manacher 学习笔记15.LCT 学习笔记16.Min_25 筛学习笔记17.Min-Max 容斥学习笔记18.位运算卷积学习笔记19.斯特林数学习笔记20.下降幂学习笔记21.普通生成函数学习笔记22.二项式反演学习笔记23.FFT 学习笔记24.原根学习笔记25.替罪羊树学习笔记26.矩阵树定理学习笔记27.高斯消元学习笔记28.LGV 引理学习笔记29.K-D tree 学习笔记30.线段树综合31.2-sat 学习笔记32.凸包学习笔记33.插头 dp 学习笔记34.整体二分学习笔记35.《具体数学》阅读笔记36.辛普森积分学习笔记杜教筛学习笔记
杜教筛被用于求解某一数论函数
算法思想
尝试构造一个函数
那么接着我们就可以简单的推得:
不难看出,只需要能够快速求解
事实上,不论
时间复杂度
在不能预处理的情况下,杜教筛的复杂度是
而在可以进行预处理的情况下,进行前
更加值得注意的是,上述时间复杂度全部建立在记忆化的基础上,因此需要采用 map
或 unordered_map
进行存储。
常见积性函数及其卷积形式
其中,
代码实现
下面以
不妨令
不难看出后半部分可以用数论分块求解。
int cnt;
int p[N+5],mu[N+5];
bool vis[N+5];
unordered_map<int,ll>sum_mu;
void EulerS(){
mu[1]=1;
for(int i=2;i<=N;i++){
if(!vis[i]){
p[++cnt]=i;
mu[i]=-1;
}
for(int j=1;p[j]<=N/i;j++){
vis[i*p[j]]=true;
if(i%p[j]==0){
mu[i*p[j]]=0;
break;
}
mu[i*p[j]]=-mu[i];
}
}
for(int i=1;i<=N;i++)mu[i]+=mu[i-1];
return ;
}//线性筛预处理
ll SumMu(ll n){
if(n<=N)return mu[n];//线性筛预处理出的答案可以不用求解
if(sum_mu[n])return sum_mu[n];//之前求解过的答案可以不用求解
ll res=1;
for(ll l=2,r;l<=n;l=r+1){
r=n/(n/l);
res-=SumMu(n/l)*(r-l+1);
}//求解前缀和
return sum_mu[n]=res;//记忆化剪枝
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下