数论总结——莫比乌斯反演
数论总结
根据此视频总结。
莫比乌斯函数\(\mu(x)\)
可以使用线性筛预处理:
int prime[MAXN],prime_tot;
bool prime_tag[MAXN];
int mu[MAXN];
void pre(){
mu[1] = 1;
for(int i = 2; i <= MAXN; i++){
if(!prime_tag[i]){
prime[++prime_tot] = i;
mu[i] = -1;
}
for(int j = 1; j <= prime_tot; j++){
if(i * prime[j] > MAXN)break;
prime_tag[i * prime[j]] = true;
if(i % prime[j] == 0){
mu[i * prime[j]] = 0;
break;
}else{
mu[i * prime[j]] = -mu[i];
}
}
}
}
狄利克雷卷积
积性函数\(f(x)\):\(\forall a,b,且gcd(a,b) = 1,则有f(ab) = f(a)f(b)\)
完全积性函数\(f(x)\):\(\forall a,b,f(ab) = f(a)f(b)\)
常见的积性函数:
- 欧拉函数 \(\varphi(x)\)
- 莫比乌斯函数 \(\mu(x)\)
- 恒等(单位)函数 \(Id(x) = x\)
- 不变函数 \(1(x) = 1\)
- 幂函数 \(Idk(x) = x^k\)
- 因子个数函数 \(d(x), d = 1 * 1\)
- 因子和函数 \(\sigma(x),\sigma = 1 * Id\)
- 因子函数 \(\sigma k(x)\)
- 狄利克雷卷积单位元 \(\epsilon = [n == 1]\)
先看如下等式:
设 \(n\)有 \(k\)个不同的质因子,则由狄利克雷卷积得出:
由二项式定理得: \((x+y)^k = \sum_{i=0}^k(_{i}^{k})x^iy^{k-i}\)
另 \(x = -1, y = 1\)得:
当 \(k = 0\)时,\(n = 1\),故证得:
莫比乌斯反演
证明一: \(g = f * 1,\mu * g = f * 1 * u = f\)
证明二: \(另k = \frac dn\),则:
因为\(nk | t\)可以写成 \(k|\frac tn\),又因为:\(\mu(\frac tn) * 1 = \sum_{k|\frac tn}\mu(k) = \sum_{nk | t}\mu(k) = \epsilon(k)\)
故上式等价于: \(\sum_tf(t)\epsilon(\frac tn) = f(n)\),所以得证。
例题
给定整数\(N\)和\(M\)。求满足 \(1\leq x \leq N,\ 1 \leq y \leq M\)且 \(gcd(x,y)\) 为质数的点对 \((x,y)\)的个数。\((1 \leq N,M \leq 1,000,000)\)
求解过程:
求\(\sum_{1 \leq i \leq N}\sum_{1 \leq j \leq M}[gcd(i,j) == p]\),\(p\)是质数
定义:
那么,\(g(n) = \sum_{n|d}f(d)\)且易知 \(g(n) = \lfloor \frac Nn \rfloor \lfloor \frac Mn \rfloor\),且 \(\sum f(p)\) 即为答案。
然后就是具体实现:
预处理 \(sum(k) := \sum_{n|k,n \in prime}\mu(\frac kn)\)
如下:
for(int i = 1; i <= prime_tot; i++){
for(int j = 1; prime[i] * j <= up; j++){
sum[prime[i] * j] += mu[j];
}
}
于是答案变为: \(ans = \sum_{1 \leq k \leq min(N,M)} \lfloor \frac Nk \rfloor \lfloor \frac Mk \rfloor sum(k)\)
对于 \(\lfloor \frac Nk \rfloor\)的计算,需要用到整除分块来加速运算过程:
先看代码:
for(int l = 1,r; l <= N; l = r + 1){
r = N / (N / l);
ans += (r - l + 1) * (N / l);
}
对于代码中的 \([l,r]\)区间的数 \(k\),\(\lfloor \frac Nk \rfloor\)的值都是 \(\lfloor \frac Nl \rfloor\),故这一段区间对答案的贡献就是 \((r-l+1)*(N / l)\)。
\(r = \lfloor \frac N{\lfloor \frac Nl \rfloor} \rfloor\)
那么为什么 \(k \in [l,r], \lfloor \frac Nk \rfloor = \lfloor \frac Nl \rfloor\)呢?
因为 \(\lfloor \frac Nl \rfloor\leq \frac Nl\),则有 \(\lfloor \frac N{\lfloor \frac Nl \rfloor} \rfloor \geq \lfloor \frac N{\frac Nl} \rfloor = l\)
故证得: \(l \leq \lfloor \frac N{\lfloor \frac Nl \rfloor} \rfloor = r\)
不妨再设 \(k = \lfloor \frac Nl \rfloor\),考虑证明当 \(\lfloor \frac Nr \rfloor = k\)时, \(r\)最大是 \(\lfloor \frac Nk \rfloor\)
故 \(r\)最大是 \(\lfloor \frac Nk \rfloor\)
因此每次将 \([l,r]\)分块,整体求和即可。
杜教筛
求 \(\sum_{i = 1}^n\mu(i),\ n \leq 10^{12}\)时,线性筛无法满足需求,因此在这里介绍杜教筛:
定义: \(M(n) := \sum_{i = 1}^n\mu(i)\)
即:\(M(n) = 1 - \sum_{i = 2}^nM(\lfloor \frac ni \rfloor)\),递归求解即可。
代码:
int mu_sum[MAXN];
unordered_map<long long, int> mp;
int mu_calc(long long n){
if(n < up)return mu_sum[n];
if(mp.count(n))return mp[n];
int ret = 1;
for(long long l = 2, r; l <= n; l = r + 1){
r = n / (n / l);
ret -= (r - l + 1) * mu_calc(n / l);
}
return mp[n] = ret;
}
\(mu\_sum[MAXN]\)表示先使用线性筛预处理出前面的项,降低时间复杂度。
欧拉函数性质
-
\(当p为质数时,当gcd(n,p) == 1,\varphi(n * p) = (p - 1) * \varphi(n),否则\varphi(n * p) = \varphi(n) * p\)
-
\(n(n > 1)\) 中与 \(n\)互质的数的和为 \(\varphi(n)/2*n\),并且 \(\varphi(n)是偶数(n > 2)\)
-
若 \(p^2 | n,则\varphi(n) = \varphi(\frac np) * p\),若 \(p\ |\ n\ 且 p^2 \nmid n\),则 \(\varphi(n) = \varphi(\frac np) * (p - 1)\)。
-
\(\varphi * 1 = Id\)
证:
\(\varphi * 1 = \sum_{d|n}\varphi(d)\)。
令 \(f(n) = \sum_{d|n}\varphi(d)\),设\(\forall n,m > 1,且gcd(n,m) = 1\),\[f(n) * f(m) = \sum_{i|n}\varphi(i) * \sum_{j|m}\varphi(j) = \sum_{i|n}\sum_{j|m}\varphi(i)*\varphi(j) = \sum_{i|n}\sum_{j|m}\varphi(i*j) = \sum_{d|nm}\varphi(d)\ \ \ \ \ (d := i* j) \]故得出 \(f(n) * f(m) = f(n * m)\),即 \(f(n)\)为积性函数。
因为\(n = p_1^{c_1}p_2^{c_2}\cdots p_k^{c_k}\),且由于\[f(p^c) = \varphi(1) + \varphi(p^1) + \cdots + \varphi(p^c) = P^0 + (p^1 - p^0) + \cdots + (p^c - p^{c-1}) = p^c \]所以
\[f(n) = f(p_1^{c_1}) * f(p_2^{c_2}) * \cdots * f(p_k^{c_k}) = p_1^{c_1} * p_2^{c_2} * \cdots * p_k^{c_k} = n \]已知 \(Id(x) = x\),
即证得: \(\varphi * 1 = Id\)