初涉莫比乌斯反演

2024-02-04 11:48
文章标签 反演 莫比 乌斯 初涉

本文主要是介绍初涉莫比乌斯反演,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        • 预备知识
          • 数论分块:
          • 莫比乌斯函数:
        • 莫比乌斯反演
        • 例题
          • BZOJ2301
          • BZOJ1101
          • LUOGU2257
          • BZOJ2005

今天我们来讨论莫比乌斯反演。我承认,反演这个东西对于数学不好的人来说确实很痛苦(比如我)。但是真正学透了,还是会发现这个东西非常巧妙。


预备知识

数论分块:

关于数论分块,我写过一篇博客,也介绍了一些例题,这里再做一个简介。
比如我们要求式子 nd=1nd ∑ d = 1 n ⌊ n d ⌋ ,那么其实我们会发现对于一段区间 i[l,r] i ∈ [ l , r ] ni ⌊ n i ⌋ 的值相同。所以我们枚举这个 l,r l , r ,就可以在 n n 的复杂度内求出这段区间值了。


莫比乌斯函数:

莫比乌斯函数 μ(x) μ ( x ) 的定义是:
1.当 d=1 d = 1 时, μ(d)=1 μ ( d ) = 1
2.当 d=Πki=1pi d = Π i = 1 k p i 其中 pi p i 为互不相同的质数,那么 μ(d)=1k μ ( d ) = − 1 k (也就是 d d 分解质因数后全是一次项,那么μ(d)为-1的项数次)
3.当 d d 含有任何质因子的次数大于2,则μ(d)=0

并且这里要介绍一些关于莫比乌斯函数的重要性质:
n|dμ(n)=[d==1] ∑ n | d μ ( n ) = [ d == 1 ] [v] [ v ] (v是一个语句)为当该语句成立时, [v]=1 [ v ] = 1 ,否则 [v]=0 [ v ] = 0
这个性质可以证明,首先 d=1 d = 1 ,那么只有一个 μ(1) μ ( 1 ) 所以值是1。否则我们将 n n 分解质因数,假设其有k个质因数,那么其实上式为 C0kC1k+C2k+Ckk C k 0 − C k 1 + C k 2 − … … + C k k (k为奇数则最后一项为负)。那么根据二项式定理,原式为0。(原式= (1+(1))k ( 1 + ( − 1 ) ) k )

n|dμ(n)n=φ(d)d ∑ n | d μ ( n ) n = φ ( d ) d 这个定理十分奇妙,然而遗憾的是我并不是特别会证。

接下去我们要讲怎么求出莫比乌斯函数,由它是积性函数的性质我们可以得到:莫比乌斯函数可以由线性筛得到,代码如下:

for(i=2;i<=MAXN;i++){if(!vis[i]) pri[++top]=i,mu[i]=-1;for(j=1;j<=top&&pri[j]*i<=MAXN;j++){vis[pri[j]*i]=1;if(i%pri[j]==0) break;mu[i*pri[j]]=-mu[i];}}

莫比乌斯反演

解决完莫比乌斯函数后,我们就可以开始反演了。首先,我应该不合时宜的直接指出莫比乌斯反演的内容:
定理:对于两个函数 F(n) F ( n ) f(n) f ( n ) 是定义在正整数集上的两个函数,并且满足条件:
F(n)=d|nf(d) F ( n ) = ∑ d | n f ( d ) 那么 f(n)=d|nμ(d)F(nd) f ( n ) = ∑ d | n μ ( d ) ∗ F ( n d )
同样也有若 F(n)=n|df(d) F ( n ) = ∑ n | d f ( d ) 那么 f(n)=n|dμ(dn)F(d) f ( n ) = ∑ n | d μ ( d n ) ∗ F ( d )
接下来我们来证明一下,这里就证明第一条,因为第二条同理。

d|nμ(d)F(nd)=d|nμ(d)d|ndf(d) ∑ d | n μ ( d ) F ( n d ) = ∑ d | n μ ( d ) ∑ d ′ | n d f ( d ′ )
我们设 nd=kd n d = k d ′ ,则 d=nkd d = n k d ′ ,所以 d|nd d | n d ′ ,因此我们可以将上面的式子改写:
d|nμ(d)d|ndf(d)=d|nf(d)d|ndμ(d) ∑ d | n μ ( d ) ∑ d ′ | n d f ( d ′ ) = ∑ d ′ | n f ( d ′ ) ∑ d | n d ′ μ ( d )
那么我们根据性质1,仅当 nd==1 n d ′ == 1 时, d|ndμ(d)=1 ∑ d | n d ′ μ ( d ) = 1 ,其它时候其都等于0。于是原式就等同于 f(n) f ( n )
所以 f(n)=d|nμ(d)F(nd) f ( n ) = ∑ d | n μ ( d ) F ( n d ) ,证明完毕。


例题

今天实在是写不动了,例题明天再补上。

好吧一天等于7月16号到8月7号,我承认我太懒了,本来打算17号写的,结果17号颓了一天,7月18号到8月2号去美国,一直也没写,于是就一直拖到今天。

总共四道例题

BZOJ2301

BZOJ2301[HAOI2011]problem b         比较模板的题,也是我做的第一道,只要容斥一下即可。

#include<bits/stdc++.h>
using namespace std;
int read(){char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
void print(int x){if(x/10) print(x/10);putchar(x%10+'0');
}
int T,a,b,c,d,k,top,ans,mu[50005],sum[50005],pri[50005],vis[50005];
int calc(int n,int m){if(n>m) swap(n,m);int l=1,r=0,res=0;n=n/k;m=m/k;while(l<=n){r=min(n/(n/l),m/(m/l));r=min(r,n);res+=(n/l)*(m/l)*(sum[r]-sum[l-1]);l=r+1;}return res;
}
int main()
{T=read();mu[1]=sum[1]=1;for(int i=2;i<=50000;i++){if(!vis[i]) pri[++top]=i,mu[i]=-1;for(int j=1;j<=top&&pri[j]*i<=50000;j++){vis[i*pri[j]]=1;if(i%pri[j]==0) break;mu[i*pri[j]]=-mu[i];}sum[i]=sum[i-1]+mu[i];}while(T--){a=read();b=read();c=read();d=read();k=read();ans=calc(b,d)-calc(a-1,d)-calc(b,c-1)+calc(a-1,c-1);print(ans);puts("");}return 0;
}

BZOJ1101

BZOJ1101[POI2007]Zap         比上一道还简单。

#include<bits/stdc++.h>
#define MAXN 50000
using namespace std;
int read(){char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
void print(int x){if(x/10) print(x/10);putchar(x%10+'0');
}
int top,T,a,b,k,mu[MAXN+5],sum[MAXN+5],pri[MAXN+5],vis[MAXN+5];
int calc(){int l=1,r=0,res=0;a=a/k;b=b/k;while(l<=a){r=min(a/(a/l),b/(b/l));r=min(r,a);res+=(sum[r]-sum[l-1])*(a/l)*(b/l);l=r+1;}return res;
}
int main()
{T=read();mu[1]=sum[1]=1;for(int i=2;i<=MAXN;i++){if(!vis[i]) pri[++top]=i,mu[i]=-1;for(int j=1;j<=top&&pri[j]*i<=MAXN;j++){vis[pri[j]*i]=1;if(i%pri[j]==0) break;mu[i*pri[j]]=-mu[i];}sum[i]=sum[i-1]+mu[i];}while(T--){a=read();b=read();k=read();if(a>b) swap(a,b);print(calc());puts("");}return 0;
}

LUOGU2257

Luogu P2257 YY的GCD         这道题求的是质数,所以在原来的基础上还要再推一步,并要预处理。

#include<bits/stdc++.h>
#define MAXN 10000000
#define ll long long
using namespace std;
ll read(){char c;ll x;while(c=getchar(),c<'0'||c>'9');x=c-'0';while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
void print(ll x){if(x/10) print(x/10);putchar(x%10+'0');
}
int T,n,m,top,l,r,mu[MAXN+5],pri[MAXN+5],vis[MAXN+5];
ll ans,sum[MAXN+5],g[MAXN+5];
int main()
{T=read();mu[1]=1;register int i,j;for(i=2;i<=MAXN;i++){if(!vis[i]) pri[++top]=i,mu[i]=-1;for(j=1;j<=top&&pri[j]*i<=MAXN;j++){vis[pri[j]*i]=1;if(i%pri[j]==0) break;mu[i*pri[j]]=-mu[i];}}for(j=1;j<=top;j++)for(i=1;i*pri[j]<=MAXN;i++) g[i*pri[j]]+=(ll)mu[i];for(i=1;i<=MAXN;i++) sum[i]=sum[i-1]+g[i];while(T--){n=read();m=read();ans=0;if(n>m) swap(n,m);l=1;while(l<=n){r=min(n/(n/l),m/(m/l));r=min(r,n);ans+=1ll*(n/l)*(m/l)*(sum[r]-sum[l-1]);l=r+1;}print(ans);puts("");}return 0;
}
BZOJ2005

BZOJ2005 [Noi2010]能量采集         这道题由于是求值,所以要做两个数论分块,并相互套起来

#include<bits/stdc++.h>
#define MAXN 100005
#define ll long long
using namespace std;
int read(){char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
ll n,m,l,r,prime[MAXN],mu[MAXN],vis[MAXN],top,gcd,sum[MAXN];
ll calc(int x){ll l=1,ans=0,N=n/x,M=m/x;while(l<=N){ll r=min(N/(N/l),M/(M/l));r=min(r,N);ans+=(sum[r]-sum[l-1])*(N/l)*(M/l);l=r+1;}return ans;
}
int main()
{n=read();m=read();if(n>m) swap(n,m);mu[1]=sum[1]=1;for(int i=2;i<=m;i++){if(!vis[i]) prime[++top]=i,mu[i]=-1;for(int j=1;j<=top&&i*prime[j]<=m;j++){vis[i*prime[j]]=1;if(i%prime[j]==0) break;mu[i*prime[j]]=-mu[i];}sum[i]=sum[i-1]+mu[i];}l=1;while(l<=n){r=min(n/(n/l),m/(m/l));r=min(r,n);gcd+=calc(l)*(r-l+1)*(l+r)/2;l=r+1;}printf("%lld",2*gcd-n*m);return 0;
}

坑终于补完了

这篇关于初涉莫比乌斯反演的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/677389

相关文章

hdu6053 TrickGCD 莫比乌斯反演

TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Problem Description You are given an array  A  , and Zhu wants to know there are how many d

初涉opencv——opencv安装问题

由于研究需要,开始学习opencv。opencv即一个视觉代码库,可供用户免费使用。       测试过程中出现了一些问题,有两位大神的博客给我很大的启发和帮助。供自己使用和后来者参考。       http://wiki.opencv.org.cn/index.php/VC_2010下安装OpenCV2.4.4,这个比较安装步骤详细,    文章链接: http://b

学习笔记 ---- 莫比乌斯反演总结

文章目录 概述前置知识数论分块狄利克雷卷积积性函数 莫比乌斯函数定义性质 莫比乌斯反演因子形式倍数形式 例题周期性字符串互质数对[NOI2010D1T1]能量采集BZOJ2820 YY的GCD[SDOI2015] 约数个数和BZOJ4407 于神之怒加强版【BZOJ2693】jzptab最小公倍数之和[bzoj3529-Sdoi2014] 数表 练习题51nod 1675 序列变换BZOJ3

BZOJ 2440 2301 莫比乌斯应用

http://www.lydsy.com/JudgeOnline/problem.php?id=2440 Description 小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些 数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而 这丝毫不影响他对其他数的热爱。  这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一 个小X讨厌

初涉Kotlin

kotlin官网链接: http://kotlinlang.org/  Kotlin是一门与Swift类似的静态类型JVM语言,由JetBrains设计开发并开源。与Java相比,Kotlin的语法更简洁、更具表达性,而且提供了更多的特性,比如,高阶函数、操作符重载、字符串模板。它与Java高度可互操作,可以同时用在一个项目中。 按照JetBrains的说法,根据他们多年的Jav

CSS初涉

为什么会有CSS?        之前仅仅通过HTML来控制页面显示时,例如改变颜色:修改样式颜色时候只能通过对每一个标签进行修改来进行。为了改进这种繁杂的操作,引入了CSS层叠样式表从而分离了页面内容以及页面显示设置。 <h2><font color=”#0000EF” face=”黑体”>CSS学习</font></h2>          下面通过使用C

莫比乌斯反演 两种形式

莫比乌斯反演在数论中占有重要的地位,许多情况下能大大简化运算。那么我们先来认识莫比乌斯反演公式。   定理:和是定义在非负整数集合上的两个函数,并且满足条件,那么我们得到结论           在上面的公式中有一个函数,它的定义如下:       (1)若,那么     (2)若,均为互异素数,那么     (3)其它情况下     对于函数

CodeForces 547C. Mike and Foam 莫比乌斯反演

题意:给定一个长度为n的数列a,和q个操作(1<= n,q <= 2*10^5, 1 <= a[i] <= 5*10^5 ) 需要维护一个多重集合Q. 每个操作给出一个下标i,如果a[i]属于Q那么把a[i]从Q中拿走,如果a[i]不属于Q,那么把a[i]加入Q中。 每次操作后询问Q中,有多少对i,j满足条件 i<j 且 gcd(a[i],a[j])=1 这个性质的维护比较困难,直

Python星载气溶胶数据处理与反演分析

在当前全球气候变化和环境污染问题日益突出的背景下,气溶胶研究显得尤为重要。气溶胶在大气中由直径范围在0.01微米至10微米固体和液体颗粒构成,直接或间接影响地球辐射平衡、气候变化和空气质量。尤其在“碳中和”目标的驱动下,研究气溶胶对“碳中和”的气候影响及其环境效应,不仅对科学研究具有重大意义,同时也为政策制定提供了重要依据。 MODIS(中分辨率成像光谱仪)和CALIOP(云-气溶胶偏振激光雷达

初涉LeNet5处理mnist (CNN卷积神经网络)

import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_dataimport osimport numpy as np#输入节点个数INPUT_NODE = 784#输出节点个数OUTPUT_NODE = 10#图片的尺寸IMAGE_SIZE = 28#通道数NUM_CHANNE