Min_25筛学习笔记

0、一些定义

  • 定义域为正整数集,陪域为复数域的函数被称为数论函数
  • \(f(x)\)是一个数论函数,若对于任意一对互质的正整数\(a,b\),有\(f(ab)=f(a)f(b)\),则称\(f(x)\)积性函数
  • \(\delta(x)\)\(x\)的最小质因子,\(\gamma(x)\)\(x\)的最大质因子。
  • \(cnt(x)\)\(x\)的质因子个数。
  • 记第\(i\)个质数为\(p_i\)。特别地,\(p_0=1\)
  • \(\pi(x)\)为不超过\(x\)的质数个数。由素数定理,\(\pi(x)=O(\frac{x}{\log x})\)

1、min_25筛

论文题:定义\(\sigma_0(n)\)\(n\)的正约数个数,求\(S(n)=\sum_{i=1}^n\sigma_0(i^k)\)\(n,k\leq 10^{10}\)

拓展:给定一个积性函数\(f(x)\),且对于任意质数\(p\)和正整数\(e\),满足:

  • \(f(p)\)是一个关于\(p\)的低次多项式。
  • 计算\(f(p^e)\)的复杂度可忽略。
  • \(S(n)=\sum_{i=1}^nf(i)\)

解法

\(f(x)=\sigma_0(x^k)\),容易发现\(f(x)\)是积性函数。

\[g(n,i)=\sum_{\substack{2\leq x\leq n\\ \delta(x)> p_i}}f(x) \]

那么\(S(n)=f(1)+g(n,0)\)

考虑计算\(g(x)\)的递推式,将\(x\)分成质数和合数两个部分,合数部分枚举最小质因子(一定\(\leq \sqrt{n}\)),质数部分单独计算,于是

\[\begin{align*} g(n,i)&=\sum_{\substack{i< j\leq \pi(\sqrt{n})}} \sum_{\substack{2\leq x\leq n\\ \delta(x)=p_j}}f(x)+\sum_{i< j\leq \pi(n)}f(p_j) \\&=\sum_{\substack{i< j\leq \pi(\sqrt{n})\\ p_j^{e+1}\leq n,e\geq 1}} \left(f(p_j^{e+1})+f(p_j^e)\sum_{\substack{2\leq x\leq \left\lfloor\frac{n}{p_j^e}\right\rfloor\\ \delta(x)> p_j}}f(x)\right)+\sum_{i< j\leq \pi(n)}f(p_j) \\&=\sum_{\substack{i< j\leq \pi(\sqrt{n})\\ p_j^{e+1}\leq n,e\geq 1}} \left(f(p_j^{e+1})+f(p_j^e)g\left(\left\lfloor\frac{n}{p_j^e}\right\rfloor,j\right)\right)+\sum_{1\leq j\leq \pi(n)}f(p_j) -\sum_{1\leq j\leq i}f(p_j)\end{align*}\]

\[h(n)=\sum_{1\leq i\leq \pi(n)}f(p_i) \]

那么

\[g(n,i)=\sum_{\substack{i< j\leq \pi(\sqrt{n})\\ p_j^{e+1}\leq n,e\geq 1}} \left(f(p_j^{e+1})+f(p_j^e)g\left(\left\lfloor\frac{n}{p_j^e}\right\rfloor,j\right)\right)+h(n)-h(p_i) \]

如果能快速计算\(h\),就可以在很低的复杂度里递推求出\(g(n,0)\)。注意到\(f\)在质数处的取值为多项式,所以只需要对于非负整数\(s\),计算\(h_s(n)=\sum_{1\leq i\leq \pi(n)}p_i^s\)。注意到\(g(n,i)\)的递推过程,我们只需要对于\(1,2,\ldots,\lfloor\sqrt{n}\rfloor,\left\lfloor\frac{n}{\lfloor\sqrt{n}\rfloor}\right\rfloor,\ldots,\left\lfloor\frac{n}{2}\right\rfloor,n\)\(O(\sqrt{n})\)个数求出\(h\)值。

\(h_s'(n,i)\),为前\(n\)个数,经过\(i\)次埃氏筛后剩下的数的\(s\)次幂之和。那么\(h_s(n)=h_s'(n,\pi(\sqrt{n}))\)

对于计算\(h_s'(n,i)\)的递推式,考虑第\(i\)轮埃氏筛的过程:

  • \(n<p_i^2\),那么不会有任何数被筛去,于是\(h_s'(n,i)=h_s'(n,i-1)\)
  • \(n\geq p_i^2\),那么被筛去的数必有质因子\(p_i\),于是应当减去\(p_i^sh_s'\left(\left\lfloor\frac{n}{p_i}\right\rfloor,i-1\right)\)。但是会有最小质因子小于\(p_i\)的数被减去,所以应当加上这部分的贡献,为\(p_i^sh_s'(p_{i-1},i-1)\)

那么

\[h_s'(n,i)=h_s'(n,i-1)-[n\geq p_i^2]p_i^s\left(h_s'\left(\left\lfloor\frac{n}{p_i}\right\rfloor,i-1\right)-h_s'(p_{i-1},i-1)\right) \]

边界条件为

\[h_s'(n,0)=\sum_{i=2}^ni^s \]

暴力实现即可。

时间复杂度

\(O(\frac{n^\frac{3}{4}}{\log n})\)

证明咕着。

例题

【模板】Min_25筛

注意\(f\)在质数\(p\)上的取值为\(p^2-p\),于是需要同时求出质数的和和平方和,即\(h_1,h_2\)。然后照着公式实现即可。

#include<cstdio>
#define ll long long
#define P 1000000007
#define inv3 333333336
#define N 200005

ll n;

int prm[N],_prm;
bool vis[N];
inline void sieve(int x){
	for(int i=2;i<=x;i++){
		if(!vis[i])
			prm[++_prm]=i;
		for(int j=1;j<=_prm&&i*prm[j]<=x;j++){
			vis[i*prm[j]]=1;
			if(!(i%prm[j]))
				break;
		}
	}
}

int sq,m;
inline int id(ll x){
	return x<=sq?x:m-n/x+1;
}
ll num[N];
int h1[N],h2[N];//h(x)=h2(x)-h1(x),h1,h2开成滚动数组 
inline void get_h(){
	while(1ll*sq*sq<=n)
		sq++;
	sq--;
	sieve(sq);
	for(int i=1;i<=sq;i++)
		num[++m]=i;
	for(int i=sq;i;i--)
		if(n/i>sq)
			num[++m]=n/i;
	for(int i=1;i<=m;i++){
		int tmp=num[i]%P;
		h1[i]=1ll*tmp*(tmp+1)/2%P-1;
		h2[i]=1ll*tmp*(tmp+1)/2%P*(2*tmp+1)%P*inv3%P-1;
	}//边界条件 
	for(int i=1;i<=_prm;i++)
		for(int j=m;num[j]>=1ll*prm[i]*prm[i];j--){//注意倒序递推 
			int k=id(num[j]/prm[i]);
			h1[j]=(h1[j]-1ll*prm[i]*(h1[k]-h1[prm[i-1]]+P)%P+P)%P;
			h2[j]=(h2[j]-1ll*prm[i]*prm[i]%P*(h2[k]-h2[prm[i-1]]+P)%P+P)%P;
		}
}

inline int g(ll x,int i){
	int k=id(x),res=((h2[k]-h1[k]+P)%P-(h2[prm[i]]-h1[prm[i]]+P)%P+P)%P;//h(x)-h(p_i)
	for(int j=i+1;j<=_prm&&1ll*prm[j]*prm[j]<=x;j++)
		for(ll pe=prm[j];pe*prm[j]<=x;pe=pe*prm[j]){
			int tmp=pe%P;
			res=(res+1ll*tmp*(tmp-1)%P*g(x/pe,j)%P)%P;//f(p_j^e)*g(x/p_j^e,j)
			res=(res+1ll*tmp*prm[j]%P*(1ll*tmp*prm[j]%P-1)%P)%P;//f(p_j^(e+1))
		}
	return res;
}

int main(){
	scanf("%lld",&n);
	get_h();
	printf("%d\n",((g(n,0))+1)%P);
}
posted @ 2020-08-21 21:32  Y25t  阅读(245)  评论(2编辑  收藏  举报