Mobius 反演与杜教筛

积性函数

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

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

常见积性函数及其性质

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

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

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

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

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

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

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

Dirichlet (狄利克雷)卷积

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

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

Mobius 函数的性质

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

Euler 函数的性质

∀ n ∈ N ∗ \forall n\in\N^* nN ∑ d ∣ n φ ( d ) = n \sum_{d|n}\varphi(d)=n dnφ(d)=n φ ∗ I = i d \varphi*I=id φI=id

Mobius 反演

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

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


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

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

杜教筛

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

和式的推导

今需计算积性函数 f ( x ) f(x) f(x) 的前缀和 S ( n ) = ∑ i = 1 n f ( i ) S(n)=\sum_{i=1}^{n}{f(i)} S(n)=i=1nf(i)
为了解决这个问题,构造积性函数 g ( x ) , h ( x ) g(x),h(x) g(x),h(x) 使 f ∗ g = h f*g=h fg=h
∑ i = 1 n h ( x ) = ∑ i = 1 n f ( x ) ∗ g ( x ) = ∑ i = 1 n ∑ d ∣ n f ( d ) g ( n d ) = ∑ d = 1 n g ( d ) ⋅ ∑ i = 1 ⌊ n d ⌋ f ( i ) = ∑ d = 1 n g ( d ) ⋅ S ( ⌊ n d ⌋ ) = g ( 1 ) ⋅ S ( n ) + ∑ d = 2 n g ( d ) ⋅ S ( ⌊ n d ⌋ ) \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} i=1nh(x)=i=1nf(x)g(x)=i=1ndnf(d)g(dn)=d=1ng(d)i=1dnf(i)=d=1ng(d)S(dn)=g(1)S(n)+d=2ng(d)S(dn)
所以 g ( 1 ) ⋅ S ( n ) = ∑ i = 1 n h ( i ) − ∑ d = 2 n g ( d ) ⋅ S ( ⌊ n d ⌋ ) g(1)·S(n)=\sum_{i=1}^{n}{h(i)}-\sum_{d=2}^{n}{g(d)·S(\lfloor\frac nd\rfloor)} g(1)S(n)=i=1nh(i)d=2ng(d)S(dn)

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

例 1

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


由上面的套路,得 g ( 1 ) ⋅ S ( n ) = ∑ i = 1 n h ( x ) − ∑ d = 2 n g ( d ) ⋅ S ( ⌊ n d ⌋ ) g(1)·S(n)=\sum_{i=1}^{n}{h(x)}-\sum_{d=2}^{n}{g(d)·S(\lfloor\frac nd\rfloor)} g(1)S(n)=i=1nh(x)d=2ng(d)S(dn)
因为 μ ∗ I = ϵ \mu*I=\epsilon μI=ϵ,所以不妨令 g = I , h = ϵ g=I,h=\epsilon g=I,h=ϵ
I ( 1 ) ⋅ S ( n ) = ∑ i = 1 n ϵ ( x ) − ∑ d = 2 n I ( d ) ⋅ S ( ⌊ n d ⌋ ) S ( n ) = 1 − ∑ d = 2 n S ( ⌊ n d ⌋ ) \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} I(1)S(n)S(n)=i=1nϵ(x)d=2nI(d)S(dn)=1d=2nS(dn)

例 2

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

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));
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值