洲阁筛法学习小计

张俊的课件如是说:

   一个对单个n有效的方法:
     f[n]表示n以内的素数个数
     c[i]表示第i个素数
     g[n][m]表示n以内不被c[1..m]整除的数的个数
      (1)
      f[n]=f[sqrt(n)]+g[n][f[sqrt(n)]]-1
      //大于sqrt(n)的合数必然会被小于等于sqrt(n)的素数去掉,而1要去掉
      (2)
      g[n][m]=g[n][m-1]-g[n/c[m]][m-1]
      //n以内不被前m-1个素数整除的数,那么还要减去被c[m]整除而不被c[1..m-1]整除的
    对于 g[n][m] 的计算的优化(很有用,当n在我们预处理的范围maxn中时):
    1)若 f[n]<=m 说明n内除了1之外所有数都可以被c[1..m]整除掉(return 1)
    2)若 f[n]<=m 说明只有n内的素数#可能#满足g[n][m],那么要去掉m个素数在加上1(return f[n]+1-m)

任之洲论文如是说:

洲阁筛是“对形式较为一般的积性函数给出一种求和算法”
  积性函数:
    设n的质因数分解为: n=Πki=1p[i]c[i] (即 n=p[1]c[1]×p[2]c[2]×...×p[k]c[k]
    有积性函数F(n)满足:
      ·当n为质数时, F(n)=G(n)
      ·当n= pc 时, F(pc)=T(pc)
      ·其他情况根据积性函数的积性, F(n)=Πki=1F(p[i]c[i]) (即 F(n)=F(p[1]c[1])×F(p[2]c[2])×...×F(p[k]c[k])
    对于Euler函数, G(p)=p1,T(pc)=(p1)p(c1)
    对于莫比乌斯函数, G(p)=1,T(pc)=0
  抛砖引玉:
    有函数 F(n)=Πki=1(p[i]c[i]+d)
    求前缀和,利用之前的表示方法, G(p)=p+dT(pc)=pc+d
  转化1:
    根据引理:对于一个在n以内的数x,x最多拥有一个大于 n 的质因子
    那么F(x)可以分两类考虑:
      ·x没有大于 n 的质因子
      ·x有一个大于 n 的质因子
    得到 ni=1F(i)=xnxnF(x)×(1+n<p[nx]pG(p))
    观察得到,后面乘上的系数只与 [nx] 有关,所以不同的系数只有 O(n) 种,可以根据 [nx] 的取值将F(x)分成 O(n) 段,每一段对应着一样的系数
    于是需要处理的就是两部分:
      · n<p[nx]pG(p)
      · xnF(x)
  G(p)的计算
    设不超过 n 的质数总共有m个,升序排序为c[1..m]
    设g[k][n][m]表示n内与前m个质数互质的所有数的k次幂之和,当m=0时就是自然数幂求和
    当i>=1时: g[k][n][m]=g[k][n][m1]c[m]k×g[k][n/c[m]][m1]
    最终得到的g[k][n][m]-1即为[1,n]范围内大于 n 的质数的k次幂之和
    根据两个引理:
      ·设正整数x,y,a,b,其中 a,bxy=[xa] 那么有 [yb]=[xab]
      ·对于所有 in [ni] 的取值有 O(n)
       对于所有 i<n [ni] 的取值也有 O(n)
    得到计算g[k][i][j]时,i的状态数只有 O(n) 种,且这些状态刚好为需要被计算的G(p)之和
  朴素实现
    朴素的实现这一个递推式需要依次枚举质数p[i],对每一个状态进行计算。
    对每一个 [nx] 中有多少个质数需要转移,时间复杂度 O(nlogn)
  优化
    当c[j+1]>i时,g[k][i][j]=1(因为只有1满足要求)
    所以当 c[j]2>ic[j] 时,即 l=[ic[j]]<c[j] 时有
       g[k][l][j1]=1
      得 g[k][i][j]=g[k][i][j1]c[j]k×g[k][i/c[j]][j1]=g[k][i][j1]c[j]k
    于是当 c[j]2>i 时的计算可以直接省掉
    那么对于每一组 [nx] 只需要转移不超过 [nx] 的质数,利用积分,可以得到:
     O(n0nxdxlogn)=O(n34logn)
  F(x)的计算
    由于 [nx] 值相同的F(x)需要乘的系数是一样的,可以直接用 [nx] 来表示状态
    同样设不超过 n 的质数总共有m个,升序排序为c[1..m]
    设f[i][j]表示只包含前j种质因子,且 [nx]=i 的F(x)之和,其中f[n][0]=1
    类似的,第一维中只有 O(n) 种状态。
  朴素实现
    由f[i][j-1]转移过来,那么枚举幂次t,设 l=[ic[j]t] ,那么:
      ·当t>1时,对 f[l][j] 的贡献为 T(c[j]t)×f[i][j1]
      ·当t=1时,对 f[l][j] 的贡献为 G(c[j])×f[i][j1]
    注意,上面看上去是反过来递推的,这是因为,我们的第一维是指 [nx]
    复杂度与G(p)的朴素实现类似。
  优化
    在G(p)的计算中省去了 c[j]2>i 的计算,这里同样考虑相似的优化措施。
    当 [nx] 不超过 n 时有: 1+n<p<[nx]pG(p)=1
    而最后的计算答案的式子为: ni=1F(i)=xnxnF(x)×(1+n<p[nx]pG(p))
    当 c[j]2>y=[nx] 时, [yc[j]]<c[j]n ,所以状态y最多只能用一个超过c[j]的质数转移,并且转移后的值的答案的贡献系数一定为1
    优化后的策略如下:
      ·对于一个质数c[i],只考虑 yc[i]2 的情况
      ·设 l=[yc[i]t] ,假如 l<c[i]2 那么这个状态在之后会被忽略,需要现在计算他对答案的贡献,也就是统计 [c[i+1],l] 范围内的G(p)之和
      ·维护每个状态最后一次转移时的c[i],统计被忽略的那一段G(p)之和
    复杂度类似
撒花!!!!!!!!!!

代码

先留个坑先。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值