我们考虑这样一个问题。
ans=n∑i=1f(i)
其中 1≤n≤1010
其中 f(i)是一个非常奇怪的函数,并不像 μ(i),φ(i),iφ(i)那样具有那么好的性质。但是满足以下条件:
1. 若 p为质数,则 f(p)是一个关于 p的多项式,比如 μ(p)=−1,φ(p)=p−1.
2. 若 p为质数,e为正整数,则 f(pe)可以很快求出。(通常是 O(1))
3.f(n)为积性函数。
然后就可以使用 min_25 筛了。(顾名思义是 min_25 发明的)
首先,我们需要知道 min_25 筛是埃氏筛的一个拓展,它的思想很大一部分借助于埃氏筛。
回想一下埃氏筛,我们是每次将最小质因子为 Pi的合数筛去,剩下的就是质数。
我们知道这些最小质因子至多为 √n,所以合数可以通过枚举最小质因子来计算,质数我们则使用另外的方法。
首先我们看质数的怎么做。
n∑i=1[i∈Prime]f(i)
根据条件 1,我们知道 f(i)是一个多项式,这样的话我们可以按照次数将 f(i)拆成 ik之和,因为 ik是一个完全积性函数(很快就有用的)。
n∑i=1[i∈Prime]ik
为了计算这个,我们需要引入一个辅助数组 g(n,j)。(鬼知道是怎么想到的)
g(n,j)=n∑i=1[i∈Prime or minp(i)>Pj]ik
其中 minp(i)表示 i的最小质因子,所以
n∑i=1[i∈Prime]ik=g(n,|P|)
既然我们要使用质数,所以我们可以先用欧拉筛把所有 ≤√n的质数筛出来,同时还要预处理 ∑ji=1[i∈Prime]ik.
我们考虑 dp 计算。既然是埃氏筛,我们就要在 g(n,j−1)中最小质因子为 Pj的合数筛去。
我们假设 P2j≤n,否则肯定不行。
首先,由于它是完全积性函数,所以 Pj可以直接提出来,剩下的减去 i≤⌊nPj⌋中的数就可以了。
这些数中要求质因子 ≥Pj,所以是 g(⌊nPj⌋,j−1),但是这里面质数被重复计算了,所以要减去里面的质数。
g(n,j)=g(n,j−1)−Pkj(g(⌊nPj⌋,j−1)−j−1∑i=1[i∈Prime]ik)
但是这样的话是 O(n∗|P|)的,时间和空间都承受不了。但是我们发现我们可以使用一个优化。
我们发现 g(n,j)中 n只有 O(√n)种取值,因为每次递归的时候是 n变为 ⌊nPj⌋,而我们发现
⌊⌊ab⌋c⌋=⌊abc⌋
所以 n只会变为 ⌊nx⌋,于是我们就直接 “手动” 离散化,这个可以看代码。
然后 g(n,j)的第二维也可以滚动数组滚掉。所以时间 O(√n∗|P|),空间 O(√n).
预处理部分终于结束了,接下来我们考虑计算答案,首先我们还是需要一个辅助数组。
S(n,j)=n∑i=1[minp(i)>Pj]f(i)
像上面说的一样,分质数和合数两类计算。
S(x,y)=g(x,|P|)−y∑i=1f(Pi)+∑Pk≤√x,k>j∑e>0,Pek≤xf(pek)(S(⌊xPek⌋,k)+[e>1])
前面两项指的是质数的部分,后面的和式是枚举合数的最小质因子 Pk和它的次数 e,
这个跟 g不同,S是要按照第二维倒着计算的,但是我们也可以使用递归的方法来计算。
S(n,0)就是最终答案。
要注意的是,1既不是质数也不是合数,所以最后要加上。
至于上面说的那个手动离散化,我们要开两个数组 id1和 id2,分别记录 ≤√n和 >√n的部分的数值的编号。这样就不用 map 了,可以省掉一个 log。
至于时间复杂度?我也不知道,总之跟杜教筛差不多,甚至有时候比杜教筛还要快。
有人说是什么 O(n34logn),或者什么 O(n1−ϵ)。总之差不多就可以了。
UOJ188#【UR #13】Sanrd
题目链接:UOJ
这道题,也算是 min_25 的一个基础应用吧。。。
我们要求 n∑i=1f(i)
按照套路,我们设
S(n,j)=n∑i=1[minp(i)>Pj]f(i)
所以
S(n,j)=∑k>j,Pk≤√n∑e>0,Pe+1k≤n(S(⌊nPek⌋,k)+Pk⌊nPk⌋∑i=Pk[i∈Prime])
素数个数用 min_25 筛可以很快求出来。
6 条评论
Icontofig · 2020年3月24日 10:17 下午
那个 g(n,j)应该是埃氏筛法的扩展的思路吧,感觉应该这就是说的 min25 筛是埃氏筛法的扩展的意思
Remmina · 2020年3月25日 12:16 上午
额,我当时学这玩意的时候似乎是听说这两者是同一个东西,不太记得清了。
AThousandMoon · 2019年5月30日 1:10 下午
https://www.cnblogs.com/AThousandMoons/p/10827172.html
AThousandMoon · 2019年5月27日 3:58 下午
对不起,S(n,j)的计算公式中后面是 k而不是 k+1。
本人能力有限,请各位指出错误。(或者各位看看代码)
Remmina · 2019年5月30日 12:57 下午
OvO…
才看懂您的意思,很抱歉耽误这么久,现在我就修改
Remmina · 2019年5月30日 1:10 下午
已经提升了 “投稿者” 权限,可以修改和删除自己已发布的文章啦,您可以自行修改了(我没找到您所描述的问题之处)