Mobius 反演与杜教筛

积性函数

积性函数 指对于所有互质的整数 aabb 有性质 f(ab)=f(a)f(b)f(ab)=f(a)f(b) 的数论函数。

特别地,若所有的整数 aabb 有性质 f(ab)=f(a)f(b)f(ab)=f(a)f(b),则称这个函数 f(x)f(x)完全积性函数

常见积性函数及其性质

  1. Mobius 函数。nN\forall n\in\N^*μ(n)={1,n=1(1)k,n=i=1kpk,0,otherwise.\mu(n)=\begin{cases}1,n=1\\ (-1)^k,n=\prod_{i=1}^{k}{p_k},\\ 0,\text{otherwise.}\end{cases}
    其中 pp 是互不相同的素数;

  2. Euler 函数。φ(n)\varphi(n) 表示不大于 nn 的、与 nn 互素的数的个数;

  3. 约数个数函数。d(n)d(n) 表示 nn 的约数个数;

  4. 约数和函数。σ(n)\sigma(n) 表示 nn 的约数之和。

完全积性函数
  1. 元函数。ϵ(x)=[x=1]\epsilon(x)=[x=1]

  2. 恒等函数。I(x)=1I(x)=1。所谓恒等就是函数值恒等于 11

  3. 单位函数。id(n)=nid(n)=n

Dirichlet (狄利克雷)卷积

两个数论函数 f(x),g(x)f(x),g(x)Dirichlet 卷积h(x)=(fg)(x)=dxf(d)g(xd)h(x)=(f*g)(x)=\sum_{d|x}f(d)g(\frac xd)

显然,Dirichlet 卷积满足交换律、结合律、分配律。而且有fϵ=ff*\epsilon=f

Mobius 函数的性质

nN\forall n\in\N^*dnμ(d)=ϵ(n)\sum_{d|n}\mu(d)=\epsilon(n)μI=ϵ\mu*I=\epsilon

Euler 函数的性质

nN\forall n\in\N^*dnφ(d)=n\sum_{d|n}\varphi(d)=nφI=id\varphi*I=id

Mobius 反演

Mobius 反演(莫比乌斯反演) 是数论数学中很重要的内容,可以用于解决很多组合数学的问题。

结论f,gf,g 为数论函数,且 f=dng(d)f=\sum_{d|n}g(d)g=dnμ(d)f(nd)g=\sum_{d|n}\mu(d)f(\frac nd)
证明: 易知f=gIf=g*I
左右两边同时卷上 μ\mu,得fμ=gIμf*\mu=g*I*\mu
因为 μI=ϵ\mu*I=\epsilon,则有fμ=gf*\mu=gg=dnμ(d)f(nd)g=\sum_{d|n}\mu(d)f(\frac nd)原命题得证。


事实上,我们做题的时候主要用以下形式。

F(x)=xdf(d)F(x)=\sum_{x|d}f(d)则有f(x)=xdμ(dx)F(d)f(x)=\sum_{x|d}\mu(\frac dx)F(d)证明与上类似,此略。

杜教筛

杜教筛 是在低于线性的时间复杂度,求一个积性函数前缀和的算法。
(找不到定义,只好自己编一个)

和式的推导

今需计算积性函数 f(x)f(x) 的前缀和S(n)=i=1nf(i)S(n)=\sum_{i=1}^{n}{f(i)}
为了解决这个问题,构造积性函数 g(x),h(x)g(x),h(x) 使fg=hf*g=h
i=1nh(x)=i=1nf(x)g(x)=i=1ndnf(d)g(nd)=d=1ng(d)i=1ndf(i)=d=1ng(d)S(nd)=g(1)S(n)+d=2ng(d)S(nd)\begin{aligned}\sum_{i=1}^{n}h(x)&=\sum_{i=1}^{n}f(x)*g(x)\\ &=\sum_{i=1}^{n}\sum_{d|n}f(d)g(\frac nd)\\ &=\sum_{d=1}^{n}g(d)·\sum_{i=1}^{\lfloor\frac nd\rfloor}{f(i)}\\ &=\sum_{d=1}^n{g(d)}·S(\lfloor\frac nd\rfloor)\\ &=g(1)·S(n)+\sum_{d=2}^{n}g(d)·S(\lfloor\frac nd\rfloor)\end{aligned}
所以g(1)S(n)=i=1nh(i)d=2ng(d)S(nd)g(1)·S(n)=\sum_{i=1}^{n}{h(i)}-\sum_{d=2}^{n}{g(d)·S(\lfloor\frac nd\rfloor)}

那么问题来了,g,hg,h 到底取什么呢?

例 1

S(n)=i=1nμ(i)S(n)=\sum_{i=1}^{n}{\mu(i)}


由上面的套路,得g(1)S(n)=i=1nh(x)d=2ng(d)S(nd)g(1)·S(n)=\sum_{i=1}^{n}{h(x)}-\sum_{d=2}^{n}{g(d)·S(\lfloor\frac nd\rfloor)}
因为 μI=ϵ\mu*I=\epsilon,所以不妨令 g=I,h=ϵg=I,h=\epsilon
I(1)S(n)=i=1nϵ(x)d=2nI(d)S(nd)S(n)=1d=2nS(nd)\begin{aligned}I(1)·S(n)&=\sum_{i=1}^{n}{\epsilon(x)}-\sum_{d=2}^{n}{I(d)·S(\lfloor\frac nd\rfloor)}\\ S(n)&=1-\sum_{d=2}^{n}{S(\lfloor\frac nd\rfloor)}\end{aligned}

例 2

S(n)=i=1nφ(i)S(n)=\sum_{i=1}^{n}{\varphi(i)}
容易想到φI=id\varphi*I=id
由上面的套路得S(n)=i=1nid=2nS(nd)S(n)=\sum_{i=1}^{n}{i}-\sum_{d=2}^{n}{S(\lfloor \frac nd\rfloor)}

luogu 杜教筛模板

luogu P4213

#include<cstdio>
#include<cstdlib>
#include<cstring>

#define reg register
typedef long long ll;
const int MAXN=5000010;
const int MOD=15e5+7;

int T,n;
bool vis[MAXN];
int p[MAXN];
int phi[MAXN];
int mu[MAXN];
ll S_phi[MAXN];
int S_mu[MAXN];
int Hmu[MOD+10];
ll Hphi[MOD+10];
int len=0;

void init(){
	memset(vis,1,sizeof(vis));
	vis[0]=vis[1]=0;phi[1]=mu[1]=1;
	for(reg ll i=2;i<=MAXN;++i){
		if(vis[i]){
			p[++len]=i;
			phi[i]=i-1;
			mu[i]=-1;
		}
		for(reg int j=1;j<=len&&(i*p[j]<=MAXN);++j){
			vis[i*p[j]]=0;
			if(i%p[j]!=0){
				phi[i*p[j]]=phi[i]*(p[j]-1);
				mu[i*p[j]]=-mu[i];
			}
			else{
				phi[i*p[j]]=phi[i]*p[j];
				mu[i*p[j]]=0;
				break;
			}
		}
	}
	S_phi[0]=S_mu[0]=0;
	for(reg int i=1;i<=MAXN;++i){
		S_phi[i]=S_phi[i-1]+phi[i];
		S_mu[i]=S_mu[i-1]+mu[i];
	}
}
ll Sphi(int x){
	if(x<MAXN) return S_phi[x];
	if(Hphi[x%MOD]) return Hphi[x%MOD];
	ll sum=0;
	for(int l=2,r;l<=x;l=r+1){
		r=x/(x/l);
		sum+=Sphi(x/l)*(r-l+1);
	}
	ll s=(1ll+x)*x/2;
	return Hphi[x%MOD]=s-sum;
}
int Smu(int x){
	if(x<MAXN) return S_mu[x];
	if(Hmu[x%MOD]) return Hmu[x%MOD];
	ll sum=0;
	for(int l=2,r;l<=x;l=r+1){
		r=x/(x/l);
		sum+=Smu(x/l)*(r-l+1);
	}
	return Hmu[x%MOD]=1-sum;
}
int main(){
	init();
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		printf("%lld %d\n",Sphi(n),Smu(n));
	}
}
posted @ 2019-07-03 11:15  TeacherDai  阅读(195)  评论(0)    收藏  举报