一些定义
数论函数
定义域为正整数的函数,一般分类如下:
- 积性函数
对于 \(\forall x,y \in N , gcd(x,y)=1\) ,若 \(f(x \cdot y)=f(x) \cdot f(y)\) ,则 \(f\) 是积性函数。 - 完全积性函数
对于 \(\forall x,y \in N\) ,若 \(f(x \cdot y)=f(x) \cdot f(y)\) ,则 \(f\) 是完全积性函数。 - 非积性函数
狄利克雷卷积
可以理解为数论函数的乘法,常用符号 \(*\) 表示。
若 \(f,g\) 均为数论函数,则有 \((f*g)(n) = \sum_{d|n}f(d)g(\frac{n}{d})\) 。
对于数论函数乘法,其单位元函数为 \(e\) :
即对于任意数论函数 \(f\) ,都有 \(f*e=f\) 。
狄利克雷卷积满足交换律和结合律。
莫比乌斯函数
莫比乌斯函数 \(\mu\) 的定义如下:
\(\mu\) 是积性函数。
性质:
- \(\forall n \in N , \sum_{d|n}\mu(d) = [n=1]\)
莫比乌斯反演中最常用的性质。
推论:\(e(n) = \sum_{d|n}\mu(d) \Rightarrow e(n) = \sum_{d|n}\mu(d)1(\frac{n}{d}) \Rightarrow e=\mu*1\) - \(\forall n \in N , \sum_{d|n}\frac{\mu(d)}{d} = \frac{\phi(n)}{n}\)
求莫比乌斯函数:
由于 \(\mu\) 是积性函数,所以 \(\mu\) 可以像素数一样筛出来。
下面给出线性筛法:
void init(){memset(is_prime,1,sizeof is_prime);is_prime[1]=0; mu[1]=1;for (int i=2;i<=MAXN;i++){ //这里的MAXN注意边界if (!is_prime[i]) continue;prime[++cnt]=i;for (int j=1;j<=cnt&&1ll*i*prime[j]<=MAXN;j++){is_prime[i*prime[j]]=0;if (i%prime[j]==0) break; // mu在这个位置上本来就是0,不用额外赋值mu[i*prime[j]]=-mu[i]; // 质因子数+1,mu乘上-1}}return;
}
莫比乌斯反演
证明:
由性质一我们已知 \(e=\mu*1\) ,
而 \(g(n) = \sum_{d|n}f(d) \;\Rightarrow\; g(n) = \sum_{d|n}f(d)1(\frac{n}{d}) \;\Rightarrow\; g=f*1\) ,
将等式两边同乘 \(\mu\) , \(g*\mu=f*(1*\mu) \;\Rightarrow\; g*\mu=f*e \;\Rightarrow\; f=g*\mu\) ,
于是 \(g(n) = \sum_{d|n}f(d) \;\Rightarrow\; f(n) = \sum_{d|n}g(d)\mu(\frac{n}{d})\) ,反之亦然。
例题(莫比乌斯函数及性质)
P3455 [POI2007] ZAP-Queries
给出 \(a,b,d\),求满足 \(1 \leq x \leq a\),\(1 \leq y \leq b\),且 \(\gcd(x,y)=d\) 的二元组 \((x,y)\) 的数量。
DATA:\(1 \leq n \leq 5 \times 10^4\),\(1 \leq d \leq a,b \leq 5 \times 10^4\)。
Solution
答案可记作 \(Ans = \sum\limits_{i=1}^{a}\sum\limits_{j=1}^{b}[\gcd(x,y)=d]\) (\(a\leq b\))
\(\because \gcd(\alpha,\beta)=1 \;\Rightarrow\; \gcd(\alpha c,\beta c)=c\)
\(
\begin{aligned}
\therefore
Ans &= \textstyle\sum\limits_{i=1}^{\lfloor\frac{a}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{b}{d}\rfloor}[\gcd(x,y)=1]\\&= \textstyle\sum\limits_{i=1}^{\lfloor\frac{a}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{b}{d}\rfloor}\sum_{d'|\gcd(x,y)}\mu(d') (性质一)\\&= \textstyle\sum\limits_{d'=1}^{\lfloor\frac{a}{d}\rfloor}\mu(d')\lfloor\frac{\lfloor\frac{a}{d}\rfloor}{d'}\rfloor\lfloor\frac{\lfloor\frac{b}{d}\rfloor}{d'}\rfloor (枚举d',交换求和顺序)
\end{aligned}
\)
由此复杂度可降至 \(O(na)\) ,但依旧不足以通过此题。
考虑数论分块,也就是把 \(\lfloor\frac{\lfloor\frac{a}{d}\rfloor}{d'}\rfloor\lfloor\frac{\lfloor\frac{b}{d}\rfloor}{d'}\rfloor\) 相同的项合并起来算,乘与 \(\sum\limits_{d'=start}^{end}\mu(d')\) 即可,这部分用前缀和。
Code
#include <bits/stdc++.h>
#define MAXN 100003
using namespace std;
int T;
int x,y,d;
int is_prime[MAXN];
int prime[MAXN]; int cnt;
int mu[MAXN];
long long sum[MAXN];
void init(){for (int i=1;i<=MAXN-2;i++) is_prime[i]=1;is_prime[1]=0; is_prime[2]=1; mu[1]=1;for (int i=2;i<=MAXN-2;i++){ // 数据范围不大,这里是nlogn筛if (!is_prime[i]) continue;mu[i]=-1;int j=2;while (1ll*i*j<=MAXN-2){is_prime[i*j]=0;if (j%i==0) mu[i*j]=0;else mu[i*j]=mu[i]*mu[j];j++;}}for (int i=1;i<=MAXN-2;i++) if (is_prime[i]) prime[++cnt]=i;for (int i=1;i<=MAXN-2;i++) sum[i]=sum[i-1]+mu[i];return;
}
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);init();cin>>T;while (T--){cin>>x>>y>>d;int N=x/d,M=y/d;long long ans=0;for (int d2=1;d2<=min(N,M);d2++){int nxt=min(N/(N/d2),M/(M/d2));ans+=1ll*(sum[nxt]-sum[d2-1])*(N/d2)*(M/d2);d2=nxt;}cout<<ans<<'\n';}return 0;
}
P2522 [HAOI2011] Problem b
对于给出的 \(n\) 个询问,每次求有多少个数对 \((x,y)\),满足 \(a \le x \le b\),\(c \le y \le d\),且 \(\gcd(x,y) = k\),\(\gcd(x,y)\) 函数为 \(x\) 和 \(y\) 的最大公约数。
DATA:\(1 \le n,k \le 5 \times 10^4\),\(1 \le a \le b \le 5 \times 10^4\),\(1 \le c \le d \le 5 \times 10^4\)。
Solution
与上题相似,加一个容斥即可。
Code
#include <bits/stdc++.h>
#define MAXN 100003
using namespace std;
int T;
int a,b,c,d,k;
int is_prime[MAXN];
int prime[MAXN]; int cnt;
int mu[MAXN];
long long sum[MAXN];
void init(){for (int i=1;i<=MAXN-2;i++) is_prime[i]=1;is_prime[1]=0; is_prime[2]=1; mu[1]=1;for (int i=2;i<=MAXN-2;i++){ //数据范围小我就不用线性筛if (!is_prime[i]) continue;mu[i]=-1;int j=2;while (1ll*i*j<=MAXN-2){is_prime[i*j]=0;if (j%i==0) mu[i*j]=0;else mu[i*j]=mu[i]*mu[j];j++;}}for (int i=1;i<=MAXN-2;i++) if (is_prime[i]) prime[++cnt]=i;for (int i=1;i<=MAXN-2;i++) sum[i]=sum[i-1]+mu[i];return;
}
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);init();cin>>T;while (T--){cin>>a>>b>>c>>d>>k;int N=b/k,M=d/k;long long ans1=0,ans2=0,ans3=0,ans4=0;for (int d2=1;d2<=min(N,M);d2++){int nxt=min(N/(N/d2),M/(M/d2));ans1+=1ll*(sum[nxt]-sum[d2-1])*(N/d2)*(M/d2);d2=nxt;}N=(a-1)/k; M=d/k;for (int d2=1;d2<=min(N,M);d2++){int nxt=min(N/(N/d2),M/(M/d2));ans2+=1ll*(sum[nxt]-sum[d2-1])*(N/d2)*(M/d2);d2=nxt;}N=(c-1)/k; M=b/k;for (int d2=1;d2<=min(N,M);d2++){int nxt=min(N/(N/d2),M/(M/d2));ans3+=1ll*(sum[nxt]-sum[d2-1])*(N/d2)*(M/d2);d2=nxt;}N=(a-1)/k; M=(c-1)/k;for (int d2=1;d2<=min(N,M);d2++){int nxt=min(N/(N/d2),M/(M/d2));ans4+=1ll*(sum[nxt]-sum[d2-1])*(N/d2)*(M/d2);d2=nxt;}cout<<ans1-ans2-ans3+ans4<<'\n';}return 0;
}
P2257 YY的GCD
给定 \(N, M\),求 \(1 \leq x \leq N\),\(1 \leq y \leq M\) 且 \(\gcd(x, y)\) 为质数的 \((x, y)\) 有多少对。
DATA:\(T = 10^4\),\(N, M \leq 10^7\)。
Solution
只需要稍微退推一下柿子(,
令 \(N \leq M\) ,
\(
\begin{aligned}
Ans &= \textstyle\sum\limits_{p \in prime}^{N}\sum\limits_{i=1}^{N}\sum\limits_{j=1}^{M}[\gcd(i,j)=p]\\&= \textstyle\sum\limits_{p \in prime}^{N}\sum\limits_{i=1}^{\lfloor\frac{N}{p}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{M}{p}\rfloor}[\gcd(i,j)=1] \\&= \textstyle\sum\limits_{p \in prime}^{N}\sum\limits_{i=1}^{\lfloor\frac{N}{p}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{M}{p}\rfloor}\sum_{d|\gcd(i,j)}\mu(d) \\&= \textstyle\sum\limits_{p \in prime}^{N}\sum\limits_{d=1}^{\lfloor\frac{N}{p}\rfloor}\mu(d)*\lfloor\frac{N}{pd}\rfloor*\lfloor\frac{M}{pd}\rfloor \\
\end{aligned}
\)
设 \(T=pd\) , \(d=\frac{T}{p}\) :
\(
\begin{aligned}
Ans &= \textstyle\sum\limits_{p \in prime}^{N}\sum\limits_{d=1}^{\lfloor\frac{N}{p}\rfloor}\mu(\frac{T}{p})*\lfloor\frac{N}{T}\rfloor*\lfloor\frac{M}{T}\rfloor \\&= \textstyle\sum\limits_{T=1}^{N}\lfloor\frac{N}{T}\rfloor\lfloor\frac{M}{T}\rfloor\sum\limits_{p|T,p \in prime}\mu(\frac{T}{p}) (枚举T,交换求和顺序) \\
\end{aligned}
\)
这下前面一部分可以用数论分块做,后半部分枚举 \(p\) 计算对 \(T\) 的贡献即可。
时间复杂度 \(O(n+T\sqrt{n})\)
Code
#include <bits/stdc++.h>
#define MAXN 10000003
using namespace std;
int T;
int n,m;
int is_prime[MAXN],prime[MAXN],cnt;
int mu[MAXN],sum[MAXN];
long long f[MAXN],sumf[MAXN];
void init(){for (int i=2;i<=MAXN-2;i++) is_prime[i]=1;mu[1]=1;for (int i=2;i<=MAXN-2;i++){ //nlogn筛似了,换成线性筛if (is_prime[i]){prime[++cnt]=i;mu[i]=-1;}for (int j=1;j<=cnt&&1ll*i*prime[j]<=MAXN-2;j++){is_prime[i*prime[j]]=0;if (i%prime[j]==0) break;mu[i*prime[j]]=-mu[i];}}for (int i=1;i<=MAXN-2;i++) sum[i]=sum[i-1]+mu[i];for (int i=1;i<=cnt;i++){for (int j=1;j<=MAXN-2&&1ll*prime[i]*j<=MAXN-2;j++){ //计算质数p对T的贡献f[prime[i]*j]+=mu[j];}}for (int i=1;i<=MAXN-2;i++) sumf[i]=sumf[i-1]+f[i];return;
}
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);init();cin>>T;while (T--){cin>>n>>m;if (n>m) swap(n,m);long long ans=0;for (int T=1;T<=n;T++){int nxt=min(n/(n/T),m/(m/T));ans+=1ll*(n/T)*(m/T)*(sumf[nxt]-sumf[T-1]);T=nxt;}cout<<ans<<'\n';}return 0;
}
例题(真正的莫比乌斯反演)
P5518 [MtOI2019] 幽灵乐团 / 莫比乌斯反演基础练习题
DATA:$$ 1\leq A,B,C\leq 10^5 \ \ \ \ 10^7 \leq p \leq 1.05\times 10^9\ \ \ \ p\in { prime} \ \ \ \ T =70$$
咕
其它东西
题单
莫比乌斯反演(函数)练习题单
参考资料
【数论】莫比乌斯函数/莫比乌斯反演
数论小白入门-- 莫比乌斯反演
【数论】莫比乌斯函数及其反演
莫比乌斯函数
关于n,欧拉函数与莫比乌斯函数的互化