learning洲阁筛

Posted yoyoball

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了learning洲阁筛相关的知识,希望对你有一定的参考价值。

问题描述

?  快速求素数处点值比较好求积性函数前缀和

大致过程

  Step1、求出一定范围内的素数处点值之和((g)

  Step2、利用上面的(g)求出一个(f)然后用(f)求出前缀和

具体过程

  (这里约定一下,在下面的内容中用(p)表示一个素数,用(P_i)表示素数列表中的第(i)项)

  这里以求(sum phi(i))为例

  首先对于素数(p)来说,(phi(p)=p-1)的,因此我们可以快速求出素数处点值的和(sum phi(p)=sum p - sum 1)

  这个时候我们定义
[ egin{aligned} g_{i,j}&=sumlimits_{k=2}^{i}[k与P_1、P_2、P_3...P_j互质或者就是其中的某个素数]k&=sumlimits_{k=2}^{i}[k是P_j的素数 或 k的最小质因子>P_j]\\end{aligned} ]
  初始化(g_{i,0}=sumlimits_{k=2}^{i} k)

  有了这个东西的话我们就可以比较快速的知道某一个范围内的素数处点值的函数值和了

  现在考虑(g_{i,j})怎么求,我们考虑从(g_{i,j-1})推到(g_{i,j})

  (这里的大体思想其实和。。之前在博客里面写到的某道题pxp。。差不多,或者说pxp其实就是洲阁筛的前半部分)

?   

  将具体的含义列出来,我们要做的就是从
[ 满足k<=P_{j-1}的素数 或 k的最小质因子>P_{j-1}的k的和 ]
  推到
[ 满足k<=P_j的素数 或 k的最小质因子>P_j的k的和 ]
  看一下我们要修改的部分,对于前半部分来说应该是加上一个(P_j)(如果在范围内的话),对于后半部分来说应该是减去一些数(不满足第二个条件),这些数满足
[ x=P_j*(一个y满足最小质因子>P_j,并且范围在[P_j,lfloorfrac{i}{P_j} floor]的数) ]
  于是乎我们非常愉快地发现后面那个括号里面的那一堆东西的和可以用回(g)来容斥一下表示!
[ sum y=g_{lfloorfrac{i}{P_j} floor,j-1}-g_{P_j-1,j-1} ]
?  然后我们就可以由(g_{i,j-1})推到(g_{i,j})
[ g_{i,j}=g_{i,j-1}-P_j(g_{lfloorfrac{i}{P_j} floor,j-1}-g_{P_j-1,j-1}) ]
  然而这里我们还可以做一个优化,如果说(i<P_j^2)的话,(g_{i,j})(g_{i,j-1})的值应该是一样的(因为不存在满足条件的(x)),所以在计算的时候我们只算(i>=P_j^2)的部分就可以了

  然而对于不同的积性函数来说,第一步的求法会有一定的差异,也许会有更加简单的求法,反正就是要求出一个函数能够快捷方便滴得到某一个范围内的素数处点值的和就好了

  

  如果一定要写一个通式的话其实就是:
[ g_{i,j}=g_{i,j-1}-F(P_j)(g_{lfloorfrac{i}{P_j} floor,j-1}-g_{P_j-1,j-1}) ]
  其中满足(F)是一个完全积性函数(因为把(P_j)提出来那步需要用到完全积性函数的性质,你并不能保证后面的那堆东西一定和(P_j)互质)

  然后(F)的话具体看最开始给的要求前缀和的函数在素数处的点值的表达式具体是啥而定,比如在这个例子里面就是(F(x)=x)

? -----------------------------------Step1 End-----------------------------------

?  接下来是用这个(g)来求(h)
[ h_{i,j}=sumlimits_{k=2}^{i}[k最小质因子>=P_j]phi(k) ]
  (如果是别的函数的话就换一下后面的(phi(k))就可以了)

  考虑这样一种枚举方式:

  每一个数我们都可以拆成
[ (最小质因子)^q*一些别的东西(可以是1) ]
  所以我们可以将上面的表达式通过枚举素数以及次方的方式写成这样:
[ h_{i,j}=sum_{q}phi(P_j^q)cdot h_{lfloor frac{i}{P_j^e} floor,j+1} ]
?  然后就可以推(h_{i,j})

  然而。。。直接搞会比较麻烦。。因为这里为了保证复杂度还是需要上面提到的(i>=P_j^2)的优化,但是这里没有那么简单,而是需要打上标记

?  所以这里写上另一种方式(貌似是min_25筛来着)
[ h_{i,j}=sum_{P_k>=P_j}sum_{q>=1,P_k^q<=i}phi(P_k^q)cdot(h_{lfloor frac{i}{P_k^q} floor,j+1}+1) ]
  后面那里要(+1)是因为要把(phi(P_k^q))的部分也算上(否则都是(一些别的东西phi(P_k^q*一些别的东西)))

  然后直接大力搜索就可以了

  边界条件:当(i<P_j^2)的时候,会发现能算进来的只有(且>=P_j且<=i)的质数处的函数值,所以可以直接返回(g_{i,max+1}-g_{P_j-1,max+1}),其中(max)是素数列表的长度

  有趣的是,并不需要记忆化ovo

  因为可以说明(h)是不会被重复调用的%%%

  然后最后的答案就是(h_{n,0})

? -----------------------------------Step2 End-----------------------------------

总的来说

  额其实就是
[ egin{aligned} g_{i,j}&=g_{i,j-1}-F(P_j)(g_{lfloorfrac{i}{P_j} floor,j-1}-g_{P_j-1,j-1})\\h_{i,j}&=sum_{P_k>=P_j}sum_{e>=1,P_k^e<=n}f(P_k^e)cdot h_{lfloor frac{i}{P_k^e} floor,j+1} end{aligned} ]
  然后(F)完全积性函数(f)是题目给的是一个积性函数,(F)是根据(f)在素数处点值的表达式构造的

  大概是这样嗯ovo

  哦然后时间复杂度是(O(frac{n^{frac{3}{4}}}{logn}))的至于证明的话。。不会qwq

  虽然说思路真的巨无敌绕不过弄懂了的话还是比较好理解的ovo(假装这两句话一点都不矛盾)

代码的话

  (还在写。。留个坑先好了qwq)

以上是关于learning洲阁筛的主要内容,如果未能解决你的问题,请参考以下文章

杜教筛进阶+洲阁筛讲解+SPOJ divcnt3

spojDIVCNTK

有用的trick

线性筛与莫比乌斯反演

[长期更新]模板&算法学习情况

蒟蒻Orion还要学的东西!