ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

杜教筛

2021-03-07 19:01:24  阅读:180  来源: 互联网

标签:lfloor frac 前缀 limits sum rfloor 杜教


前置知识

莫比乌斯反演

算法简介

用于计算数论函数前缀和。

思想

设有一个数论函数 \(f\) ,要计算它的前缀和,即 \(S(n)=\sum \limits_{i=1}^n f_i\) 。
再找一个数论函数 \(g\) ,考虑它们狄利克雷卷积的前缀和:
\(\sum \limits_{i=1}^n (f*g)(i)=\sum \limits_{i=1}^n \sum \limits_{d|i}f(d)g(\frac{i}{d})=\sum \limits_{d=1}^n g(d) \sum \limits_{i=1}^{\lfloor \frac{n}{d} \rfloor} f(i)=\sum \limits_{d=1}^n g(d)S(\lfloor \frac{n}{d} \rfloor)\) .
发现这个式子的第一项,即 \(g(1)S(n)\) ,就是我们要求的 \(S(n)\) 。
用前缀和的思想, \(g(1)S(n)=\sum \limits_{i=1}^n g(i)S(\lfloor \frac{n}{i} \rfloor)-\sum \limits_{i=2}^n g(i)S(\lfloor \frac{n}{i} \rfloor)\) 。
因为 \(g(1)S(n)\) 就是我们要求解的东西,所以把前一部分换成 \(\sum \limits_{i=1}^n (f*g)(i)\) ,得到 \(g(1)S(n)=\sum \limits_{i=1}^n (f*g)(i)-\sum \limits_{i=2}^n g(i)S(\lfloor \frac{n}{i} \rfloor)\) 。
这样,如果找的积性函数 \(g\) 有比较好的性质,能够快速算出 \(\sum \limits_{i=1}^n (f*g)(i)\) 和 \(g\) 的前缀和,就可以数论分块,同时递归处理 \(S(\lfloor \frac{n}{i} \rfloor)\) ,从而得到 \(S(n)\) 了。
直接写,复杂度是 \(O(n^{\frac{3}{4}})\) 。
但是,这个做法还可以优化。可以用线性筛先筛出前 \(O(n^{\frac{2}{3}})\) 个数,后面再用杜教筛。这样做,复杂度是 \(O(n^{\frac{2}{3}})\) 。

例子

1.求 \(\varphi\) 的前缀和。
有性质 \(\varphi*1=id\) ,同样把上面的 \(f\) 取为 \(\varphi\) , \(g\) 取为 \(1\) 即可。(\(id(n)=n\))

int PHI(int x)
{
	if(x<N) return phi[x];//已经筛出来的部分
	if(ans[x]) return ans[x];
	int sum=(1+x)*x/2,l=0,r=1;
	while(l<=x)
	{
		l=r+1;
		if(x/l) r=MIN(x/(x/l),x);
		else r=x;
		sum-=(r-l+1)*PHI(x/l);
	}
	return ans[x]=sum;
}

2.求 \(\mu\) 的前缀和。
有性质 \(\mu*1=\varepsilon\) ,那么,把上面的 \(f\) 取为 \(\mu\) , \(g\) 取为 \(1\) 即可。(\(\varepsilon(n)=[n=1]\))

int MU(int x)
{
	if(x<N) return mu[x];
	if(ans[x]) return ans[x];
	int sum=1,l=0,r=1;
	while(l<=x)
	{
		l=r+1;
		if(x/l) r=MIN(x/(x/l),x);
		else r=x;
		sum-=(r-l+1)*MU(x/l);
	}
	return ans[x]=sum;
}

标签:lfloor,frac,前缀,limits,sum,rfloor,杜教
来源: https://www.cnblogs.com/zhs1/p/14491045.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有