如果函数f:N->R,满足对于任意一对互质的正整数p,q,都有f(pq)=f(p)*f(q),则称f为积性函数。
常见的积性函数:
欧拉函数f(n)=1~n 中与n互质的数的数量
这个比较容易证:
设x=p1^a1*p2^a2*……*pm1^am1
y=q1^b1*q2^b2*……*qm2^bm2
则f(x)=x*(1-1/p1)*(1-1/p2)*……*(1-1/pm1)
f(y)=y*(1-1/q1)*(1-1/q2)*……*(1-1/qm2)
由于x和y互质,则对于任意的正整数i(1<=i<=m1)以及正整数j(1<=j<=m2)均有pi != qj
这是显然的
所以f(xy)=x*y*(1-1/p1)*(1-1/p2)*……*(1-1/pm1)*(1-1/q1)*(1-1/q2)*……*(1-1/qm2)=f(x)*f(y)
d(n)=n的正因子数量也是一个积性函数
证明:
设x=p1^a1*p2^a2*……*pm1^am1
y=q1^b1*q2^b2*……*qm2^bm2
则d(x)=(1+a1)*(1+a2)*……*(1+am1)
d(y)=(1+b1)*(1+b2)*……*(1+bm2)
由于x和y互质,则对于任意的正整数i(1<=i<=m1)以及正整数j(1<=j<=m2)均有pi != qj
所以d(xy)=(1+a1)*(1+a2)*……*(1+am1)*(1+b1)*(1+b2)*……*(1+bm2)=d(x)*d(y)
积性函数有一个重要性质:
如果f(n),g(n)都是积性函数,则h(n)=f(n)*g(n)也是一个积性函数
证明:
h(xy)=f(xy)*g(xy)=f(x)*f(y)*g(x)*g(y)=f(x)*g(x)*f(y)*g(y)=h(x)*h(y)
这个性质非常重要!
设f是积性函数,假设n=p1^a1*p2^a2*……*pm^am
那么有f(n)=f(p1^a1)*f(p2^a2)*……*f(pm^am)
这是显然的,因为由于p1~pm是m个互不相同的质数,所以对于任意的i,j满足(1<=i,j<=m)有pi^ai与pj^aj互质。
那这些东西有什么用处呢?
假如我们要求f(1~n),常规做法我们是直接一个一个求,这样复杂度是n^1.5,而我们利用欧拉筛来求的话复杂度就可以变为O(n)。
最常见的一个例子就是线性计算欧拉函数的时候我们就用到了积性函数这个性质。
下面直接给出通用模板:
//f[i]为待求积性函数
//cnt[i]为i的最小质因子的次数(有时候不需要求,比如欧拉筛)
//cal(i,j)=f[prime[i]^j]
void init()
{
f[1]=1;
for(int i=2;i<N;i++)
{
if(!vis[i])
{
prime[++tt]=i;
f[i]=cal(i,1);
cnt[i]=1;//最小质因子就是自己
}
for(int j=1;j<=tt&&i*prime[j]<N;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0)//prime[j]是i的最小质因子
{
cnt[i*prime[j]]=cnt[i]+1;
f[i*prime[j]]=f[i]/cal(prime[j],cnt[i])*cal(prime[j],cnt[i]+1);
break;
}
cnt[i*prime[j]]=1;//i*prime[j]的最小质因子是prime[j],且只含有1个
f[i*prime[j]]=f[i]*cal(prime[j],1);
}
}
}