莫比乌斯反演

莫比乌斯反演

今天是世纪性的一天,因为我又又又又来看数论且弄懂了qwq。

前置知识:交换求和,整除分块(我们需要将式子化为整数分块可以解决的形式)

莫比乌斯函数

-> μ ( d ) \mu(d) μ(d)

函数构成
  • d = 1 d=1 d=1时, μ ( d ) = 1 \mu(d)=1 μ(d)=1

  • d = Π i = 1 k d=\Pi_{i=1}^k d=Πi=1k p i p_i pi,且 p i p_i pi为互异质数时, μ ( d ) = ( − 1 ) k \mu(d)=(-1)^k μ(d)=(1)k;
    (也就是就是 d d d分解质因数后,没有幂次大于2的质因子,此时函数值根据分解的个数决定)

  • 只要 d d d含有任何质因子的幂次大于等于2,则 μ ( d ) \mu(d) μ(d) = 0 =0 =0

性质
  • 对于任意正整数 n n n, Σ d ∣ n \Sigma_{d|n} Σdn Σ d ∣ n \Sigma_{d|n} Σdn

  • 对于任意正整数 n n n, Σ d ∣ n \Sigma_{d|n} Σdn μ ( d ) n \frac{\mu(d)}{n} nμ(d) = ϕ ( d ) n = \frac{\phi(d)}{n} =nϕ(d)

code

O ( n ) O(n) O(n)版本,如果超时请去学杜教筛

void get_mu(int n)
{
    mu[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!vis[i]){prim[++cnt]=i;mu[i]=-1;}
        for(int j=1;j<=cnt&&prim[j]*i<=n;j++)
        {
            vis[prim[j]*i]=1;
            if(i%prim[j]==0)break;
            else mu[i*prim[j]]=-mu[i];
        }
    }
 }

注意

整除_百度百科 (baidu.com)

a ∣ b a|b ab的意思为b除以a为整数(b为a的倍数),即a能整除b

莫比乌斯反演
定理

F ( n ) F(n) F(n) f ( n ) f(n) f(n)是定义在非负整数集合上的两个函数,它们之间满足关系

F ( n ) = Σ d ∣ n f ( d ) F(n)=\Sigma_{d|n} f(d) F(n)=Σdnf(d)

那么就有结论

f ( n ) = Σ d ∣ n μ ( d ) F ( n d ) f(n)=\Sigma_{d|n} \mu(d) F(\frac{n}{d}) f(n)=Σdnμ(d)F(dn)

这个定理即为莫比乌斯反演定理.

还有另外一种形式

F ( n ) = Σ n ∣ d f ( d ) F(n)=\Sigma_{n|d} f(d) F(n)=Σndf(d)

f ( n ) = Σ n ∣ d μ ( d n ) F ( d ) f(n)=\Sigma_{n|d}\mu(\frac{d}{n})F(d) f(n)=Σndμ(nd)F(d)

证明

这里只给出第一种形式的证明,第二种形式同理.

由定理可设

F ( n d ) = Σ i ∣ n d f ( i ) F(\frac{n}{d})=\Sigma_{i|\frac{n}{d}} f(i) F(dn)=Σidnf(i)

Σ d ∣ n μ ( d ) F ( n d ) = Σ d ∣ n μ ( d ) Σ i ∣ n d f ( i ) \Sigma_{d|n} \mu(d)F(\frac{n}{d})=\Sigma_{d|n} \mu(d) \Sigma_{i|\frac{n}{d}} f(i) Σdnμ(d)F(dn)=Σdnμ(d)Σidnf(i)

= Σ d i ∣ n μ ( d ) f ( i ) =\Sigma_{di|n}\mu(d) f(i) =Σdinμ(d)f(i)//这一步没看懂的去看交换求和,接下来都为交换求和的知识点

= Σ i ∣ n Σ d ∣ n i μ ( d ) f ( i ) =\Sigma_{i|n}\Sigma_{d|\frac{n}{i}}\mu(d) f(i) =ΣinΣdinμ(d)f(i)

= Σ i ∣ n f ( i ) Σ d ∣ n i μ ( d ) =\Sigma_{i|n}f(i)\Sigma_{d|\frac{n}{i}}\mu(d) =Σinf(i)Σdinμ(d)

= Σ i ∣ n f ( i ) Σ d ∣ n i ( μ ( d ) = [ n i = 1 ] ) =\Sigma_{i|n}f(i)\Sigma_{d|\frac{n}{i}}(\mu(d)=[\frac{n}{i}=1]) =Σinf(i)Σdin(μ(d)=[in=1])

//(莫比乌斯函数性质1)只有在 n i = 1 \frac{n}{i}=1 in=1时才有值,其他时候为0;

//因此 n = i n=i n=i

//故 Σ i ∣ n f ( i ) = f ( n ) \Sigma_{i|n}f(i)=f(n) Σinf(i)=f(n)

= f ( n ) =f(n) =f(n)

得证.

例题

P2257 YY的GCD - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

观察定理可知,我们在反演前需要设出 F ( n ) F(n) F(n) f ( d ) f(d) f(d)

而对于这种有 g c d gcd gcd的题目,一般套路为将 f ( d ) f(d) f(d)设为 g c d ( i , j ) gcd(i,j) gcd(i,j) = d =d =d的对数,将 F ( n ) F(n) F(n)设为 g c d ( i , j ) = n gcd(i,j)=n gcd(i,j)=n或n的倍数的对数;

(对数为满足条件的 ( i , j ) (i,j) (i,j)对数)

即有

f ( d ) = Σ i = 1 n Σ j = 1 m [ g c d ( i , j ) = d ] f(d)=\Sigma_{i=1}^n\Sigma_{j=1}^m[gcd(i,j)=d] f(d)=Σi=1nΣj=1m[gcd(i,j)=d]

F ( n ) = Σ n ∣ d f ( d ) = ⌊ N n ⌋ ⌊ M n ⌋ F(n)=\Sigma_{n|d}f(d)=\lfloor \frac{N}{n}\rfloor\lfloor \frac{M}{n}\rfloor F(n)=Σndf(d)=nNnM

带入反演公式后有

f ( n ) = Σ n ∣ d μ ( d n ) F ( d ) f(n)=\Sigma_{n|d}\mu(\frac{d}{n})F(d) f(n)=Σndμ(nd)F(d)

接下来开始计算答案

a n s = Σ k ∈ p r Σ i = 1 n Σ j = 1 m [ g c d ( i , j ) = k ] ans=\Sigma_{k\in pr}\Sigma_{i=1}^n\Sigma_{j=1}^m[gcd(i,j)=k] ans=ΣkprΣi=1nΣj=1m[gcd(i,j)=k]

= Σ k ∈ p r f ( k ) =\Sigma_{k\in pr}f(k) =Σkprf(k)//反演

= Σ k ∈ p r Σ k ∣ d μ ( d k ) F ( d ) =\Sigma_{k\in pr}\Sigma_{k|d}\mu(\frac{d}{k})F(d) =ΣkprΣkdμ(kd)F(d)

为了将 d d d消去,设 d k = v \frac{d}{k}=v kd=v

= Σ k ∈ p r Σ v = 1 m i n ( ⌊ n k ⌋ , ⌊ m k ⌋ ) μ ( v ) F ( v k ) =\Sigma_{k \in pr}\Sigma_{v=1}^{min(\lfloor \frac{n}{k}\rfloor,\lfloor \frac{m}{k}\rfloor)}\mu(v)F(vk) =ΣkprΣv=1min(⌊kn,km⌋)μ(v)F(vk)

= Σ k ∈ p r Σ v = 1 m i n ( ⌊ n k ⌋ , ⌊ m k ⌋ ) μ ( v ) ⌊ m v k ⌋ ⌊ n v k ⌋ =\Sigma_{k \in pr}\Sigma_{v=1}^{min(\lfloor \frac{n}{k}\rfloor,\lfloor \frac{m}{k}\rfloor)}\mu(v)\lfloor \frac{m}{vk}\rfloor\lfloor \frac{n}{vk}\rfloor =ΣkprΣv=1min(⌊kn,km⌋)μ(v)vkmvkn

= Σ k ∈ p r Σ v k = 1 m i n ( n , m ) μ ( v ) ⌊ m v k ⌋ ⌊ n v k ⌋ =\Sigma_{k \in pr}\Sigma_{vk=1}^{min(n,m)}\mu(v)\lfloor \frac{m}{vk}\rfloor\lfloor \frac{n}{vk}\rfloor =ΣkprΣvk=1min(n,m)μ(v)vkmvkn

由于我们需要将式子向整除分块,即形如 Σ i = 1 n ⌊ n i ⌋ \Sigma_{i=1}^n \lfloor\frac{n}{i}\rfloor Σi=1nin的形式

所以我们设 T = v k T=vk T=vk

= Σ k ∈ p r Σ T = 1 m i n ( n , m ) μ ( T k ) ⌊ m T ⌋ ⌊ n T ⌋ =\Sigma_{k \in pr}\Sigma_{T=1}^{min(n,m)}\mu(\frac{T}{k})\lfloor \frac{m}{T}\rfloor\lfloor \frac{n}{T}\rfloor =ΣkprΣT=1min(n,m)μ(kT)TmTn

= Σ T = 1 m i n ( n , m ) ⌊ m T ⌋ ⌊ n T ⌋ Σ k ∈ p r , k ∣ T μ ( T k ) =\Sigma_{T=1}^{min(n,m)}\lfloor \frac{m}{T}\rfloor\lfloor \frac{n}{T}\rfloor\Sigma_{k \in pr,k|T}\mu(\frac{T}{k}) =ΣT=1min(n,m)TmTnΣkpr,kTμ(kT)

接下来就可以开始运算啦

g g g Σ k ∈ p r , k ∣ T μ ( T k ) \Sigma_{k \in pr,k|T}\mu(\frac{T}{k}) Σkpr,kTμ(kT),即 g [ T ] g[T] g[T]

s u m sum sum g g g的前缀和,用来计算整除分块.

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int N=1e7+10;

ll g[N],sum[N],mu[N];
int T,n,m,pr[N],cnt;
bool st[N];

void get_mu()
{
	mu[1]=1;
	for(int i=2;i<=N;++i)
	{
		if(!st[i])mu[i]=-1,pr[++cnt]=i;
		for(int j=1;j<=cnt&&i*pr[j]<=N;++j)
		{
			st[i*pr[j]]=true;
			if(i%pr[j]==0)break;
			else mu[i*pr[j]]=-mu[i];
		}
	}	
	
	for(int i=1;i<=cnt;++i)
		for(int j=1;j*pr[i]<=N;++j)
			g[1ll*pr[i]*j]+=mu[j];
			
	for(int i=1;i<=N;++i)sum[i]=sum[i-1]+g[i];
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	
	get_mu();
	
	cin>>T;
	while(T--)
	{
		cin>>n>>m;
		if(n>m)swap(n,m);
		ll ans=0;
		for(int l=1,r;l<=n;l=r+1)
		{
			r=min(n/(n/l),m/(m/l));
			ans+=1ll*(m/l)*(n/l)*(sum[r]-sum[l-1]);
		}
		cout<<ans<<'\n';
	}
	return 0;
}

日拱一卒,功不唐捐!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值