积性函数学习笔记
定义
满足$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;
}
看都看了,顺手点个推荐呗 :)

浙公网安备 33010602011771号