[笔记] Powerful Number 筛
定义#
Powerful Number(以下简称 PN)筛类似于杜教筛,可以拿来求一些积性函数的前缀和。
要求:
假设现在要求积性函数 的前缀和 ,需要存在一个函数 满足:
- 是积性函数。
- 易求前缀和。
- 对于质数 , 。
Powerful Number#
定义:每个质因子次数都 的数。
性质:
-
所有的 PN 都可以表示成 。
-
以内的 PN 至多是 个,可以积分证明。
枚举:线性筛出 以内的质数,dfs 搜索每个质数的指数,时间复杂度 。
原理#
首先,构造出合适的 ,记 。
然后考虑另一个函数 ,满足 ,故 也为积性函数,且 仅在 PN 处不为 。
首先考虑质数 ,,故 .
又 是积性函数,故对于非 PN 的数 ,都有 。
现在,根据 有:
那么现在要考虑的问题就只是 PN 处 的取值如何计算,也就是计算 。
根据 ,可得 。
也可以考虑直接推 的式子。
复杂度分析#
可以分为计算 和搜索两部分进行分析。
-
根据 内的素数个数为 ,因此时间复杂度为 。
此处计算的上界较为宽松,可以根据题目优化。
-
对于搜索部分,由于 以内的 PN 至多有 个,所以至多搜索 次。对于每一个 PN,假设计算 的时间复杂度为 ,则第二部分的复杂度为 。
特别地,若杜教筛计算 ,则时间复杂度为杜教筛的时间复杂度,即 。
对于空间复杂度,其瓶颈在于存储 ,若使用二维数组 记录, 表示 的值,则空间复杂度为 。
void Enum(int x, LL d, int Hd){
if(x > pcnt || (__int128) d * pri[x] * pri[x] > K){
MOD(Ans += G(K / d) % mod * Hd % mod - mod);
return;
}
Enum(x + 1, d, Hd);
int cnt = 2; LL s = (LL) pri[x] * pri[x];
while((__int128) d * s <= K){
Enum(x + 1, d * s, (LL) Hd * H[x][cnt] % mod);
if((__int128) s * pri[x] > K) break;
s *= pri[x], ++cnt;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下