筛法板子

发现自己一般推完莫反后不会筛,所以回来看看。
常用线性筛来筛质数同时得到各个积性函数的值。
先说几个常用的东西怎么筛,首先约数个数和的筛法.
O(nlog n)的筛法是显然的,不多说(调和级数枚举倍数)。
注:下面p为质数,s为n中分解出的质因子的指数。
就还是先看我们要求的目标,直接唯一分解定理,我们的目标是dx为约数个数。

dx=pi|xsi+1

然后这个东西还是分情况讨论去筛。
对于质因数来说,dx=2
考虑我们现在找到一个不能整除x的质因数:

dx×pi=dx×2

这个显然。
如果找到一个可以整除x的质因数,si是x的质因子pi的指数:

dx×pi=dx/(si+1)×(si+2)

这个可以维护下si,那么:

si(x×pi)=six+1

对于质数该值为1,然后直接筛即可。

f[1]=1;
for(int i=2;i<=n;i++){
	if(!vis[i]) p[++tot]=i,f[i]=2,g[i]=1;
	for(int j=1;j<=tot&&i*p[j]<=n;j++){
		int tmp=i*p[j];
		vis[tmp]=1;
		if(i%p[j]==0){
			mu[tmp]=0;
			g[tmp]=g[i]+1;
			f[tmp]=f[i]/(g[i]+1)*(g[tmp]+1);
			break;
		}
		g[tmp]=1;
		f[tmp]=f[i]*[g[tmp]+1];
		mu[tmp]=-mu[i];
	}
}

然后是约数和。
O(nlog n)不说了。
考虑将一个数根据唯一分解定理分解。

n=pi|npisi

那么有n的约数和σ(n)满足

σ(n)=pi|nj=0sipij

筛的时候只有两种情况,一种该因数在当前基数i中没有出现过。
那么有:

σ(i×pk)=σ(i)×(pk+1)

另外一种情况则是该因数出现过(sk表示在i中pk的指数):

σ(i×pk)=σ(i)×j=0sk+1pkj/j=0skpkj

然后可以发现后面的两个东西可以单独维护,而且二者之间存在关系(设该值在i上为gi):

gi×pk=gi×pk+1

然后就可以线性筛了。

mu[1]=1,g[1]=1,f[1]=1;
for(int i=2;i<=s;++i){
	if(!vis[i])p[++tot]=i,mu[i]=-1;
	for(int j=1;j<=tot&&p[j]*i<=s;++j){
		int tmp=i*p[j];
		vis[tmp]=1;
		if(!(i%p[j])){
			mu[tmp]=0;
			g[tmp]=g[i]*p[j]+1;
			f[tmp]=f[i]/g[i]*g[tmp];
			break;
		}
		g[tmp]=p[j]+1;
		f[tmp]=f[tmp]*f[p[j]];
		mu[tmp]=-mu[i];
	}
}

因为有

i=0kxk=(xk+11)/(x1)

这个东西还可以写成另一个形式:

mu[1]=f[1]=g[1]=1;
for(int i=2;i<=s;++i){
	if(!vis[i])p[++tot]=i,mu[i]=-1,pw[i]=i*i,f[i]=i+1;
	for(int j=1;j<=tot&&p[j]*i<=s;++j){
		int tmp=i*p[j];
		vis[tmp]=1;
		if(!(i%p[j])){
			mu[tmp]=0;
			pw[tmp]=pw[i]*p[j];
			f[tmp]=f[i]*(pw[tmp]-1)/(pw[i]-1);
			break;
		}
		pw[tmp]=p[j]*p[j];
		f[tmp]=f[tmp]*f[p[j]];
		mu[tmp]=-mu[i];
	}
}
posted @   SLS-wwppcc  阅读(13)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示