积性函数学习笔记

定义

满足$f(n)=f(a)*f(b)的性质 $(a与b互质)的函数被称为积性函数

求法

因为该函数有这种性质,我们不用对于每一项都单独求解,利用这个性质可以在$O(n)$的时间内求出1~n的所有函数值

这样对于每个n,拆分成$n=\prod p_i^{a_i}$,这样$f(n)=\prod f(p_i^{a_i})$

具体而言,先用欧拉筛求出每个数n的最小质因数minp[n]

求完之后对于每一个数n,计算minp[n]对f(n)的贡献,然后将n除以minp[n],继续计算,如此反复直到n=1

应用

判断一个函数是否是积性函数:看它是否能表示成其质因数函数值的乘积

常见积性函数:

φ(n) -欧拉函数 
μ(n) -莫比乌斯函数:关于非平方数的质因子数目 
gcd(n,k) -最大公因子,当k固定的情况 
d(n) -n的正因子数目 
$σ^k (n)$ -n的所有正因子的k次方之和

另外,还有如下性质:

两个积性函数的积和狄利克雷卷积、积性函数的k次方,也是积性函数

 

 

例题

【BZOJ1968】约数研究

求1~n的d(n)之和

代码

#include<bits/stdc++.h>
using namespace std;
#define N 1000000 
bool  tag[N];
int p[N/10],minp[N],ind[N],f[N],cnt;
int qpow(int a,int b)
{
	int res=1;
	while(b)
	{
		if(b&1) res*=a;
		a*=a;
		b>>=1;
	}
	return res;
}
int main()
{
	int n;
	cin>>n;
	for(int i=2;i<=n;i++) 
	{
		if(!tag[i]) p[++cnt]=i,minp[i]=i,ind[i]=1;
		for(int j=1;j<=cnt&&p[j]*i<=n;j++)
		{
			int t=p[j]*i;
			minp[t]=p[j];
			tag[t]=true;
			if(i%p[j]==0) 
			{
				ind[t]=ind[i]+1;
				break;
//这里退出的原因是因为i中含有p[j],那么下一个树p[j+1]*i=p[j]*p[j+1]*k的最小因子就不是p[j+1]了,会影响答案 } else ind[t]=1; } } f[1]=1; for(int i=2;i<=n;i++) { int x=i; f[i]=1; while(x>1) { f[i]*=(ind[x]+1); x/=qpow(minp[x],ind[x]); } } int tot=0; for(int i=1;i<=n;i++) tot+=f[i]; cout<<tot; }

  

 

posted @ 2021-07-21 11:45  linzhuohang  阅读(156)  评论(0编辑  收藏  举报