序:
关于这个筛法,此前是在学习了杜教筛的基础上的,杜教筛有良好的复杂度O(n23)O(n^\frac{2}{3})O(n32),而且实现简单。唯一的不足之处就是函数本身需要满足一些特殊的条件(即我们需要找另一个积性函数,使其与所求函数的狄利克雷卷积是一个很容易求前缀的式子),而且与函数本身的积性性质没有太大关系。后来接触到洲阁筛,这种筛法是一种解决更加广泛的积性函数前缀和,但是实在不太好写(因为我太菜了),后来在秦皇岛,复旦的温老师介绍了一个新的筛法,不过后来老师没怎么讲这个,因为时间不够了,然后就很匆忙提了一下。对于这么偏的东西,我还是去刷其他的题去了。。。后来一次偶然的机会,我遇到了一个类似的需要用这种方法的题目,后来就决定自己学EES,网上一查,发现根本就没有这样的东西。。。后来按照课件,我大概是明白了一点,但是还有后半部的问题,我始终没有解决,而且这个东西我周围没一个人会,网上也查不到。。。于是这篇写了一半草稿在18年9月就一直封存着了,后来就慢慢忘了。。。直到前几天,偶然的机会,又谈到这个问题,终于搞明白了。
提出问题:
f(x)是一个积性函数,且当x=pk时(p为质数),f(x)是一个关于p的多项式f(x)是一个积性函数,且当x=p^k时(p为质数),f(x)是一个关于p的多项式f(x)是一个积性函数,且当x=pk时(p为质数),f(x)是一个关于p的多项式
求S(n)=∑i=1nf(i),n<=1012S(n)=\sum_{i=1}^nf(i),n<=10^{12}S(n)=i=1∑nf(i),n<=1012
问题的一般化描述便是如此。显然问题的难点是在n的数量级上。这种筛法便是解决相关问题,如果n小于10810^{8}108,我们可以用欧拉线性筛在O(n)O(n)O(n)的时间复杂度解决这个问题。
分析:
设自然数集合N={x∣2<=x<=n}N=\{ x|2<=x<=n\}N={x∣2<=x<=n},我们按照一种划分标准,将这个集合里的数分成两部分。
这个标准是,先把一个数xxx唯一分解:x=∏i=1kpiai,pi为质数,pi<pi+1,ai>=1x=\prod_{i=1}^k p_i^{a_i},p_i为质数,p_i<p_{i+1},a_i>=1x=i=1∏kpiai,pi为质数,pi<pi+1,ai>=1
划分标准为:我们取这个数的最大质因子pkp_kpk,若这个质因子的次数即ak=1a_k=1ak=1,即x属于集合N1N_1N1,反之,x属于N2N_2N2,即ak>1a_k>1ak>1
显然N1∩N2=∅,N1∪N2=NN_1\cap N_2=\emptyset,N_1\cup N_2=NN1∩N2=∅,N1∪N2=N
对N1,N2N_1,N_2N1,N2中的数,我们来讨论一下他们的性质,很容易证明有:∀x∈N1,则(若存在)其次大质因子pk−1<n\forall x \in N_1,则(若存在)其次大质因子p_{k-1}<\sqrt n∀x∈N1,则(若存在)其次大质因子pk−1<n
∀x∈N2,则其最大质因子pk<=n\forall x \in N_2,则其最大质因子p_{k}<=\sqrt n∀x∈N2,则其最大质因子pk<=n
解决问题的第一步:
现在我们枚举一类数xxx,我们记PxP^xPx是xxx的质因子的集合,
我们枚举集合NNN中的数x,满足:∀p∈Px,p<=n\forall p\in P^x,p<=\sqrt n∀p∈Px,p<=n
满则条件的x构成一个集合,记为N12N^{\frac{1}{2}}N21,
那么实现的时候,我们可以DFSn\sqrt nn以内的质因子.当n<1013n<10^{13}n<1013时,∣N12∣≈n34logn|N^{\frac{1}{2}}|\approx \frac{n^{\frac{3}{4}}}{logn}∣N21∣≈lognn43,这里的证明比较复杂,暂不讨论。
接下来,我们记Lx为xL_x为xLx为x的最大质因子。
对于答案来说这个集合里的还少了质因子是大于n\sqrt nn的数
现在我们枚举来集合N12N^{\frac{1}{2}}N21,
∀x∈N12如果 x∈N1,则S(n)+=f(x)∗∑Lx<i<=nx[i是质数]∗f(i)反之,S(n)+=f(x)\forall x \in N^{\frac{1}{2}}\\
如果\ x\in N_1,则S(n)+=f(x)*\sum_{L_x<i<=\frac{n}{x}}[i是质数]*f(i)\\反之,S(n)+=f(x)∀x∈N21如果 x∈N1,则S(n)+=f(x)∗Lx<i<=xn∑[i是质数]∗f(i)反之,S(n)+=f(x)
显然,这里是利用了函数的积性来求得那些质因子是大于n\sqrt nn的数对于答案的贡献。
在实现的时候,显然当Lx>=nxL_x>=\frac{n}{x}Lx>=xn,可以及时退出,不然对效率还是有影响的。
问题转化为一个子问题:
那么现在的问题就只剩下求∑Lx<i<=nx[i是质数]∗f(i)\sum_{L_x<i<=\frac{n}{x}}[i是质数]*f(i)Lx<i<=xn∑[i是质数]∗f(i),
我们记:g(n)=∑i=1n[i是质数]∗f(i)g(n)=\sum_{i=1}^n[i是质数]*f(i)g(n)=i=1∑n[i是质数]∗f(i),
则求的是g(⌊nx⌋)−g(Lx)g(\lfloor\frac{n}{x}\rfloor)-g(L_x)g(⌊xn⌋)−g(Lx)
因为LxL_xLx是小于n\sqrt nn,所以这里欧拉筛也可以处理,反正这个很容易处理。
现在问题的真正关键是求g(⌊nx⌋)(或g(n))g(\lfloor\frac{n}{x}\rfloor)(或g(n))g(⌊xn⌋)(或g(n)),
回过头观察f(x)f(x)f(x),f(x)f(x)f(x)是只有在x为质数是才有多项式,我们不妨设一个函数f′(x)f'(x)f′(x),他对于全体整数都满足这个多项式,那么我们发现:g(n)=∑i=1n[i是质数]∗f(i)=∑i=1n[i是质数]∗f′(i)g(n)=\sum_{i=1}^n[i是质数]*f(i)=\sum_{i=1}^n[i是质数]*f'(i)g(n)=i=1∑n[i是质数]∗f(i)=i=1∑n[i是质数]∗f′(i),
而多向式的求和,是很容易的!我们只要把不符合条件的筛掉就可以,并且显然f′(x)f'(x)f′(x)是完全积性函数,即f′(ab)=f′(a)f′(b)f'(ab)=f'(a)f'(b)f′(ab)=f′(a)f′(b)
假设这个多项式有k次:∑ikaipi\sum_i^{k}a_ip^i∑ikaipi,那么实际上我们只要执行下面的算法k+1次,aia_iai这个系数在执行完以后在乘上就行,所以我们只要先讨论:f′(p)=pkf'(p)=p^kf′(p)=pk,这个东西求和不难,组合数学的东西
解决子问题:
我们可以回想一下Eratosthenes SieveEratosthenes\ SieveEratosthenes Sieve的筛法是怎么样的。从小到大,枚举质数把后面的是这个是质数倍数的数去除。实际上这个也是这样的:从小到大枚举p∈P,且p<=n从小到大枚举p \in P,且p<=\sqrt n从小到大枚举p∈P,且p<=n
给定ppp以后,我们枚举i:从大到小枚举i∈N,当i<p2停止枚举从大到小枚举i\in N,当i<p^2停止枚举从大到小枚举i∈N,当i<p2停止枚举
利用f′(x)f'(x)f′(x)的完全积性,执行下面的操作:g[i]−=(g[⌊ip⌋]−g[p−1])∗f′(p)g[i]-=(g[\lfloor\frac{i}{p}\rfloor]-g[p-1])*f'(p)g[i]−=(g[⌊pi⌋]−g[p−1])∗f′(p)
解释一下:g[i]g[i]g[i]和g(i)g(i)g(i)含义略有不同,g[i]g[i]g[i]代表一个变量,存的是一个值,g(i)g(i)g(i)是一个精确的定义的函数,值不允许改变。
解释这个操作的意思,就是每次我们枚举ppp以后的目的是,把所有的以ppp为最小质因子的数,消除影响,就是减去他们的贡献,g(p−1)∗f(p)g(p-1)*f(p)g(p−1)∗f(p)里面是所有的以ppp为最大质因子的贡献,是减多了。在把他们加回来的操作。
需要注意一点的:g[n]g[n]g[n]在最初始的情况下,被填充的是∑i=2nf′(i)=∑i=2nik\sum_{i=2}^nf'(i)=\sum_{i=2}^ni^k∑i=2nf′(i)=∑i=2nik.
回过头来看这个操作,假设我们枚举完了第kkk个质数即pkp_kpk,我们观察一下g[n]g[n]g[n]里面的内容是什么,为方便起见,我们设为g[n]kg[n]_kg[n]k:g[n]k=∑i=1kf(pi)+∑pk<x<=n[x没有前k个质因子]∗f(x)g[n]_k=\sum_{i=1}^kf(p_i)+\sum_{p_{k}<x<=n}[x没有前k个质因子]*f(x)g[n]k=i=1∑kf(pi)+pk<x<=n∑[x没有前k个质因子]∗f(x)
设P′={p∈P,且p<=n}P'=\{p \in P,且p<=\sqrt n \}P′={p∈P,且p<=n}
则:g[n]∣P′∣=∑i=1∣P′∣f(pi)+∑pk<x<=n[x没有前∣P′∣个质因子]∗f(x)g[n]_{|P'|}=\sum_{i=1}^{|P'|}f(p_i)+\sum_{p_{k}<x<=n}[x没有前|P'|个质因子]*f(x)g[n]∣P′∣=i=1∑∣P′∣f(pi)+pk<x<=n∑[x没有前∣P′∣个质因子]∗f(x)
显然,这里的xxx都是质数,那么到这里:g[n]等于g(n)g[n]等于g(n)g[n]等于g(n)
到这里真确性得以验证,到这里问题得到了理论上的解决。
关于复杂度:
温老师的ppt说每个可能用到的g(i)g(i)g(i),只会在遍历不超过n\sqrt nn的质数访问到,因此,每个i贡献的时间复杂为O(ilogi)=O(ilog i)O(\frac{\sqrt i}{log \sqrt i})=O(\frac{\sqrt i}{log\ i})O(logii)=O(log ii)
总时间复杂度为:O(∑i=1nilog i+∑i=1nnilog ni)≈O(n34log n)O(\sum_{i=1}^{\sqrt n}\frac{i}{log\ i}+\sum_{i=1}^{\sqrt n}\frac{\sqrt \frac{n}{i}}{log\ \sqrt \frac{n}{i}})\approx O(\frac{n^{\frac{3}{4}}}{log\ n})O(i=1∑nlog ii+i=1∑nlog inin)≈O(log nn43)
举个例子:
比如求g(12)g(12)g(12),只要枚举2,3两个因子就可以了,
初始g[12]=∑i=212f(12)g[12]=\sum_{i=2}^{12}f(12)g[12]=∑i=212f(12),(g[1]=0g[1]=0g[1]=0,显然)
枚举222,则g[12]−=(g[6]−g[1])∗f′(2)g[12]-=(g[6]-g[1])*f'(2)g[12]−=(g[6]−g[1])∗f′(2)
那么:g[12]=f′(2)+f′(3)+f′(4)+f′(5)+f′(6)+f′(7)+f′(8)+f′(9)+f′(10)+f′(11)+f′(12)g[12]=f'(2)+f'(3)+\sout{f'(4)}+f'(5)+\sout{f'(6)}+f'(7)+\sout{f'(8)}+f'(9)+\sout{f'(10)}+f'(11)+\sout{f'(12)}g[12]=f′(2)+f′(3)+f′(4)+f′(5)+f′(6)+f′(7)+f′(8)+f′(9)+f′(10)+f′(11)+f′(12)枚举333,则g[12]−=(g[4]−g[2])∗f′(3)g[12]-=(g[4]-g[2])*f'(3)g[12]−=(g[4]−g[2])∗f′(3),这时g[4]=f′(2)+f′(3)g[4]=f'(2)+f'(3)g[4]=f′(2)+f′(3),乘上f′(3)f'(3)f′(3)以后,相当于把f′(6)f'(6)f′(6)给多减了,因为枚举2时已经把f′(6)f'(6)f′(6)减了,所以这里g[2]=f′(2)g[2]=f'(2)g[2]=f′(2),乘上f′(3)f'(3)f′(3),又把f′(6)f'(6)f′(6)加回来。
那么:g[12]=f′(2)+f′(3)+f′(4)+f′(5)+f′(6)+f′(7)+f′(8)+f′(9)+f′(10)+f′(11)+f′(12)g[12]=f'(2)+f'(3)+\sout{f'(4)}+f'(5)+\sout{f'(6)}+f'(7)+\sout{f'(8)}+\sout{f'(9)}+\sout{f'(10)}+f'(11)+\sout{f'(12)}g[12]=f′(2)+f′(3)+f′(4)+f′(5)+f′(6)+f′(7)+f′(8)+f′(9)+f′(10)+f′(11)+f′(12)
循环结束。
如有错误欢迎指正。