Powerful Number 筛

数学 / 数论

本地源文件:docs/math__number-theory__powerful-number.md

Powerful Number 筛

定义

Powerful Number(以下简称 PN)筛类似于杜教筛,或者说是杜教筛的一个扩展,可以拿来求一些积性函数的前缀和.

要求

  • 存在一个函数 𝑔g 满足:
  • 𝑔g 是积性函数.
  • 𝑔g 易求前缀和.
  • 对于质数 𝑝p,𝑔(𝑝) =𝑓(𝑝)g(p)=f(p)

假设现在要求积性函数 𝑓f 的前缀和 𝐹(𝑛) =∑𝑛𝑖=1𝑓(𝑖)F(n)=∑i=1nf(i)

Powerful Number

定义 :对于正整数 𝑛n,记 𝑛n 的质因数分解为 𝑛 =∏𝑚𝑖=1𝑝𝑒𝑖𝑖n=∏i=1mpiei.𝑛n 是 PN 当且仅当 ∀1 ≤𝑖 ≤𝑚,𝑒𝑖 >1∀1≤i≤m,ei>1

性质 1 :所有 PN 都可以表示成 𝑎2𝑏3a2b3 的形式.

证明 :若 𝑒𝑖ei 是偶数,则将 𝑝𝑒𝑖𝑖piei 合并进 𝑎2a2 里;若 𝑒𝑖ei 为奇数,则先将 𝑝3𝑖pi3 合并进 𝑏3b3 里,再将 𝑝𝑒𝑖−3𝑖piei−3 合并进 𝑎2a2 里.

性质 2 :𝑛n 以内的 PN 至多有 𝑂(√𝑛)O(n) 个.

证明 :考虑枚举 𝑎a,再考虑满足条件的 𝑏b 的个数,有 PN 的个数约等于

∫√𝑛13√𝑛𝑥2d𝑥=𝑂(√𝑛)∫1nnx23dx=O(n)

那么如何求出 𝑛n 以内所有的 PN 呢?线性筛找出 √𝑛n 内的所有素数,再 DFS 搜索各素数的指数即可.由于 𝑛n 以内的 PN 至多有 𝑂(√𝑛)O(n) 个,所以至多搜索 𝑂(√𝑛)O(n) 次.

PN 筛

首先,构造出一个易求前缀和的积性函数 𝑔g,且满足对于素数 𝑝p,𝑔(𝑝) =𝑓(𝑝)g(p)=f(p).记 𝐺(𝑛) =∑𝑛𝑖=1𝑔(𝑖)G(n)=∑i=1ng(i)

然后,构造函数 ℎ =𝑓/𝑔h=f/g,这里的 // 表示狄利克雷卷积除法.根据狄利克雷卷积的性质可以得知 ℎh 也为积性函数,因此 ℎ(1) =1h(1)=1.𝑓 =𝑔 ∗ℎf=g∗h,这里 ∗∗ 表示狄利克雷卷积.

对于素数 𝑝p,𝑓(𝑝) =𝑔(1)ℎ(𝑝) +𝑔(𝑝)ℎ(1) =ℎ(𝑝) +𝑔(𝑝) ⟹ ℎ(𝑝) =0f(p)=g(1)h(p)+g(p)h(1)=h(p)+g(p)⟹h(p)=0.根据 ℎ(𝑝) =0h(p)=0 和 ℎh 是积性函数可以推出对于非 PN 的数 𝑛n 有 ℎ(𝑛) =0h(n)=0,即 ℎh 仅在 PN 处取有效值.

现在,根据 𝑓 =𝑔 ∗ℎf=g∗h

𝐹(𝑛)=𝑛∑𝑖=1𝑓(𝑖)=𝑛∑𝑖=1∑𝑑|𝑖ℎ(𝑑)𝑔(𝑖𝑑)=𝑛∑𝑑=1⌊𝑛𝑑⌋∑𝑖=1ℎ(𝑑)𝑔(𝑖)=𝑛∑𝑑=1ℎ(𝑑)⌊𝑛𝑑⌋∑𝑖=1𝑔(𝑖)=𝑛∑𝑑=1ℎ(𝑑)𝐺(⌊𝑛𝑑⌋)=𝑛∑𝑑=1𝑑 is PNℎ(𝑑)𝐺(⌊𝑛𝑑⌋)F(n)=∑i=1nf(i)=∑i=1n∑d|ih(d)g(id)=∑d=1n∑i=1⌊nd⌋h(d)g(i)=∑d=1nh(d)∑i=1⌊nd⌋g(i)=∑d=1nh(d)G(⌊nd⌋)=∑d=1d is PNnh(d)G(⌊nd⌋)

𝑂(√𝑛)O(n) 找出所有 PN,计算出所有 ℎh 的有效值.对于 ℎh 有效值的计算,只需要计算出所有 ℎ(𝑝𝑐)h(pc) 处的值,就可以根据 ℎh 为积性函数推出 ℎh 的所有有效值.现在对于每一个有效值 𝑑d,计算 ℎ(𝑑)𝐺(⌊𝑛𝑑⌋)h(d)G(⌊nd⌋) 并累加即可得到 𝐹(𝑛)F(n)

下面考虑计算 ℎ(𝑝𝑐)h(pc),一共有两种方法:一种是直接推出 ℎ(𝑝𝑐)h(pc) 仅与 𝑝,𝑐p,c 有关的计算公式,再根据公式计算 ℎ(𝑝𝑐)h(pc);另一种是根据 𝑓 =𝑔 ∗ℎf=g∗h 有 𝑓(𝑝𝑐) =∑𝑐𝑖=0𝑔(𝑝𝑖)ℎ(𝑝𝑐−𝑖)f(pc)=∑i=0cg(pi)h(pc−i),移项可得 ℎ(𝑝𝑐) =𝑓(𝑝𝑐) −∑𝑐𝑖=1𝑔(𝑝𝑖)ℎ(𝑝𝑐−𝑖)h(pc)=f(pc)−∑i=1cg(pi)h(pc−i),现在就可以枚举素数 𝑝p 再枚举指数 𝑐c 求解出所有 ℎ(𝑝𝑐)h(pc)

过程

  1. 构造 𝑔g
  2. 构造快速计算 𝐺G 的方法
  3. 计算 ℎ(𝑝𝑐)h(pc)
  4. 搜索 PN,过程中累加答案
  5. 得到结果

对于第 3 步,可以直接根据公式计算,可以使用枚举法预处理打表,也可以搜索到了再临时推.

性质

以使用第二种方法计算 ℎ(𝑝𝑐)h(pc) 为例进行分析.可以分为计算 ℎ(𝑝𝑐)h(pc) 和搜索两部分进行分析.

对于第一部分,根据 𝑂(√𝑛)O(n) 内的素数个数为 𝑂(√𝑛log⁡𝑛)O(nlog⁡n),每个素数 𝑝p 的指数 𝑐c 至多为 log⁡𝑛log⁡n,计算 ℎ(𝑝𝑐)h(pc) 需要循环 (𝑐 −1)(c−1) 次,由此有第一部分的时间复杂度为 𝑂(√𝑛log⁡𝑛⋅log⁡𝑛⋅log⁡𝑛) =𝑂(√𝑛log⁡𝑛)O(nlog⁡n⋅log⁡n⋅log⁡n)=O(nlog⁡n),且这是一个宽松的上界.根据题目的不同还可以添加不同的优化,从而降低第一部分的时间复杂度.

对于搜索部分,由于 𝑛n 以内的 PN 至多有 𝑂(√𝑛)O(n) 个,所以至多搜索 𝑂(√𝑛)O(n) 次.对于每一个 PN,根据计算 𝐺G 的方法不同,时间复杂度也不同.例如,假设计算 𝐺(⌊𝑛𝑑⌋)G(⌊nd⌋) 的时间复杂度为 𝑂(1)O(1),则第二部分的复杂度为 𝑂(√𝑛)O(n)

特别地,若借助杜教筛计算 𝐺(⌊𝑛𝑑⌋)G(⌊nd⌋),则第二部分的时间复杂度为杜教筛的时间复杂度,即 𝑂(𝑛23)O(n23).因为若事先计算一次 𝐺(𝑛)G(n),并且预先使用线性筛优化和用支持快速随机访问的数据结构(如 C++ 中的 std::mapstd::unordered_map)记录较大的值,则杜教筛过程中用到的 𝐺(⌊𝑛𝑑⌋)G(⌊nd⌋) 都是线性筛中记录的或者 std::map 中记录的,这一点可以直接用程序验证.

对于空间复杂度,其瓶颈在于存储 ℎ(𝑝𝑐)h(pc).若使用二维数组 𝑎a 记录,𝑎𝑖,𝑗ai,j 表示 ℎ(𝑝𝑗𝑖)h(pij) 的值,则空间复杂度为 𝑂(√𝑛log⁡𝑛⋅log⁡𝑛) =𝑂(√𝑛)O(nlog⁡n⋅log⁡n)=O(n)

例题

Luogu P5325【模板】Min_25 筛

题意 :给定积性函数 𝑓(𝑝𝑘) =𝑝𝑘(𝑝𝑘 −1)f(pk)=pk(pk−1),求 ∑𝑛𝑖=1𝑓(𝑖)∑i=1nf(i)

易得 𝑓(𝑝) =𝑝(𝑝 −1) =id⁡(𝑝)𝜑(𝑝)f(p)=p(p−1)=id⁡(p)φ(p),构造 𝑔(𝑛) =id⁡(𝑛)𝜑(𝑛)g(n)=id⁡(n)φ(n)

考虑使用杜教筛求 𝐺(𝑛)G(n),根据 (id ⋅𝜑) ∗id =id2(id⋅φ)∗id=id2 可得 𝐺(𝑛) =∑𝑛𝑖=1𝑖2 −∑𝑛𝑑=2𝑑 ⋅𝐺(⌊𝑛𝑑⌋)G(n)=∑i=1ni2−∑d=2nd⋅G(⌊nd⌋)

之后 ℎ(𝑝𝑘)h(pk) 的取值可以枚举计算,这种方法不再赘述.

此外,此题还可以直接求出 ℎ(𝑝𝑘)h(pk) 仅与 𝑝,𝑘p,k 有关的公式,过程如下:

𝑓(𝑝𝑘)=𝑘∑𝑖=0𝑔(𝑝𝑘−𝑖)ℎ(𝑝𝑖)⟺𝑝𝑘(𝑝𝑘−1)=𝑘∑𝑖=0𝑝𝑘−𝑖𝜑(𝑝𝑘−𝑖)ℎ(𝑝𝑖)⟺𝑝𝑘(𝑝𝑘−1)=𝑘∑𝑖=0𝑝2𝑘−2𝑖−1(𝑝−1)ℎ(𝑝𝑖)⟺𝑝𝑘(𝑝𝑘−1)=ℎ(𝑝𝑘)+𝑘−1∑𝑖=0𝑝2𝑘−2𝑖−1(𝑝−1)ℎ(𝑝𝑖)⟺ℎ(𝑝𝑘)=𝑝𝑘(𝑝𝑘−1)−𝑘−1∑𝑖=0𝑝2𝑘−2𝑖−1(𝑝−1)ℎ(𝑝𝑖)⟺ℎ(𝑝𝑘)−𝑝2ℎ(𝑝𝑘−1)=𝑝𝑘(𝑝𝑘−1)−𝑝𝑘+1(𝑝𝑘−1−1)−𝑝(𝑝−1)ℎ(𝑝𝑘−1)⟺ℎ(𝑝𝑘)−𝑝ℎ(𝑝𝑘−1)=𝑝𝑘+1−𝑝𝑘⟺ℎ(𝑝𝑘)𝑝𝑘−ℎ(𝑝𝑘−1)𝑝𝑘−1=𝑝−1f(pk)=∑i=0kg(pk−i)h(pi)⟺pk(pk−1)=∑i=0kpk−iφ(pk−i)h(pi)⟺pk(pk−1)=∑i=0kp2k−2i−1(p−1)h(pi)⟺pk(pk−1)=h(pk)+∑i=0k−1p2k−2i−1(p−1)h(pi)⟺h(pk)=pk(pk−1)−∑i=0k−1p2k−2i−1(p−1)h(pi)⟺h(pk)−p2h(pk−1)=pk(pk−1)−pk+1(pk−1−1)−p(p−1)h(pk−1)⟺h(pk)−ph(pk−1)=pk+1−pk⟺h(pk)pk−h(pk−1)pk−1=p−1

再根据 ℎ(𝑝) =0h(p)=0,通过累加法即可推出 ℎ(𝑝𝑘) =(𝑘 −1)(𝑝 −1)𝑝𝑘h(pk)=(k−1)(p−1)pk

参考代码

---|---

### [「LOJ #6053」简单的函数](https://loj.ac/problem/6053)

给定 𝑓(𝑛)f(n)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7):

𝑓(𝑛)=⎧{ {⎨{ {⎩1𝑛=1𝑝⊕𝑐𝑛=𝑝𝑐𝑓(𝑎)𝑓(𝑏)𝑛=𝑎𝑏 and 𝑎⟂𝑏f(n)={1n=1p⊕cn=pcf(a)f(b)n=ab and a⟂b![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)

易得:

𝑓(𝑝)={𝑝+1𝑝=2𝑝−1otherwisef(p)={p+1p=2p−1otherwise![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)

构造 𝑔g![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 为

𝑔(𝑛)={3𝜑(𝑛)2∣𝑛𝜑(𝑛)otherwiseg(n)={3φ(n)2∣nφ(n)otherwise![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)

易证 𝑔(𝑝) =𝑓(𝑝)g(p)=f(p)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 且 𝑔g![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 为积性函数.

下面考虑求 𝐺(𝑛)G(n)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7).

𝐺(𝑛)=𝑛∑𝑖=1[𝑖mod2=1]𝜑(𝑖)+3𝑛∑𝑖=1[𝑖mod2=0]𝜑(𝑖)=𝑛∑𝑖=1𝜑(𝑖)+2𝑛∑𝑖=1[𝑖mod2=0]𝜑(𝑖)=𝑛∑𝑖=1𝜑(𝑖)+2⌊𝑛2⌋∑𝑖=1𝜑(2𝑖)G(n)=∑i=1n[imod2=1]φ(i)+3∑i=1n[imod2=0]φ(i)=∑i=1nφ(i)+2∑i=1n[imod2=0]φ(i)=∑i=1nφ(i)+2∑i=1⌊n2⌋φ(2i)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)

记 𝑆1(𝑛) =∑𝑛𝑖=1𝜑(𝑖)S1(n)=∑i=1nφ(i)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7),𝑆2(𝑛) =∑𝑛𝑖=1𝜑(2𝑖)S2(n)=∑i=1nφ(2i)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7),则 𝐺(𝑛) =𝑆1(𝑛) +2𝑆2(⌊𝑛2⌋)G(n)=S1(n)+2S2(⌊n2⌋)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7).

当 2 ∣𝑛2∣n![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 时,有

𝑆2(𝑛)=𝑛∑𝑖=1𝜑(2𝑖)=𝑛2∑𝑖=1(𝜑(2(2𝑖−1))+𝜑(2(2𝑖)))=𝑛2∑𝑖=1(𝜑(2𝑖−1)+2𝜑(2𝑖))=𝑛2∑𝑖=1(𝜑(2𝑖−1)+𝜑(2𝑖))+𝑛2∑𝑖=1𝜑(2𝑖)=𝑛∑𝑖=1𝜑(𝑖)+𝑆2(𝑛2)=𝑆1(𝑛)+𝑆2(⌊𝑛2⌋)S2(n)=∑i=1nφ(2i)=∑i=1n2(φ(2(2i−1))+φ(2(2i)))=∑i=1n2(φ(2i−1)+2φ(2i))=∑i=1n2(φ(2i−1)+φ(2i))+∑i=1n2φ(2i)=∑i=1nφ(i)+S2(n2)=S1(n)+S2(⌊n2⌋)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)

当 2 ∤𝑛2∤n![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 时,有

𝑆2(𝑛)=𝑆2(𝑛−1)+𝜑(2𝑛)=𝑆2(𝑛−1)+𝜑(𝑛)=𝑛−1∑𝑖=1𝜑(𝑖)+𝑆2(𝑛−12)+𝜑(𝑛)=𝑆1(𝑛)+𝑆2(⌊𝑛2⌋)S2(n)=S2(n−1)+φ(2n)=S2(n−1)+φ(n)=∑i=1n−1φ(i)+S2(n−12)+φ(n)=S1(n)+S2(⌊n2⌋)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)

综上,有 𝑆2(𝑛) =𝑆1(𝑛) +𝑆2(⌊𝑛2⌋)S2(n)=S1(n)+S2(⌊n2⌋)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7).

𝑆1S1![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 可以用杜教筛求,𝑆2S2![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 直接按照公式推,这样 𝐺G![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 也可以求出来了.

参考代码

---|---

习题

参考资料

本页面最近更新: 2026/1/7 08:56:54,更新历史 发现错误?想一起完善?在 GitHub 上编辑此页! 本页面贡献者:Enter-tainer, Tiphereth-A, Backl1ght, StudyingFather, Xeonacid, cy1999, Great-designer, iamtwz, Ir1d, kenlig, ksyx, LaDeXX, lrherqwq, Marcythm, xyf007 本页面的全部内容在CC BY-SA 4.0SATA 协议之条款下提供,附加条款亦可能应用