张俊的课件如是说:
一个对单个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)=p−1,T(pc)=(p−1)p(c−1)
对于莫比乌斯函数,G(p)=−1,T(pc)=0
抛砖引玉:
有函数F(n)=Πki=1(p[i]c[i]+d)
求前缀和,利用之前的表示方法,G(p)=p+d,T(pc)=pc+d
转化1:
根据引理:对于一个在n以内的数x,x最多拥有一个大于n√的质因子
那么F(x)可以分两类考虑:
·x没有大于n√的质因子
·x有一个大于n√的质因子
得到∑ni=1F(i)=∑x≤n且x没有大于n√的质因子F(x)×(1+∑n√<p≤[nx]且p为质数G(p))
观察得到,后面乘上的系数只与[nx]有关,所以不同的系数只有O(n√)种,可以根据[nx]的取值将F(x)分成O(n√)段,每一段对应着一样的系数
于是需要处理的就是两部分:
·∑n√<p≤[nx]且p为质数G(p)
·∑x没有大于n√的质因子F(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][m−1]−c[m]k×g[k][n/c[m]][m−1]
最终得到的g[k][n][m]-1即为[1,n]范围内大于n√的质数的k次幂之和
根据两个引理:
·设正整数x,y,a,b,其中a,b≤x,y=[xa]那么有[yb]=[xab]
·对于所有i≤n√,[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>i≥c[j]时,即l=[ic[j]]<c[j]时有
g[k][l][j−1]=1
得g[k][i][j]=g[k][i][j−1]−c[j]k×g[k][i/c[j]][j−1]=g[k][i][j−1]−c[j]k
于是当c[j]2>i时的计算可以直接省掉
那么对于每一组[nx]只需要转移不超过[nx]−−−√的质数,利用积分,可以得到:
O(∫n√0nx√dxlogn)=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][j−1]
·当t=1时,对f[l][j]的贡献为G(c[j])×f[i][j−1]
注意,上面看上去是反过来递推的,这是因为,我们的第一维是指[nx]
复杂度与G(p)的朴素实现类似。
优化
在G(p)的计算中省去了c[j]2>i的计算,这里同样考虑相似的优化措施。
当[nx]不超过n√时有:1+∑n√<p<[nx]且p为质数G(p)=1
而最后的计算答案的式子为:∑ni=1F(i)=∑x≤n且x没有大于n√的质因子F(x)×(1+∑n√<p≤[nx]且p为质数G(p))
当c[j]2>y=[nx]时,[yc[j]]<c[j]≤n√,所以状态y最多只能用一个超过c[j]的质数转移,并且转移后的值的答案的贡献系数一定为1
优化后的策略如下:
·对于一个质数c[i],只考虑y≥c[i]2的情况
·设l=[yc[i]t],假如l<c[i]2那么这个状态在之后会被忽略,需要现在计算他对答案的贡献,也就是统计[c[i+1],l]范围内的G(p)之和
·维护每个状态最后一次转移时的c[i],统计被忽略的那一段G(p)之和
复杂度类似
撒花!!!!!!!!!!
代码
先留个坑先。