莫比乌斯反演 学习笔记
莫比乌斯函数
定义
\(\mu\) 表示莫比乌斯函数,是一个由容斥系数所构成的函数, \(\mu{(d)}\) 的定义是:
1.当d等于1时, \(\mu{(d)} = 1\)
2.当d由k个不同的质因子组成时,\(\mu{(d)} = (-1)^k\) (注:一定是互不相同的质因子
3.其它情况\(\mu{(d)} = 0\)
性质
1.对于任意正整数n,都有\(\sum\limits_{d|n}\mu{(d)} = [n = 1]\)
即当n等于1时 原式等于1,其它情况下 ,原式等于0
首先当n等于1时 ,显然答案是1
当n不等于1时,答案与那些\(\mu\)值是0的项肯定没有关系
现在考虑n有k个互不相同的质因子 它们分别组合
假定i个质因子相互组合 此时的方案数有\(\binom{k}{i}\)种
而此时的\(\mu\)值为\((-1)^k\)
所以对于一个非1的n 最终的求和式子也就是
\((-1)^1*\binom{k}{1}+(-1)^2*\binom{k}{2}+...+(-1)^k*\binom{k}{k}+1\)(最后的1是\(\mu{(1)}\) 因为通过质因子相乘是无法组合出1的,所以要把漏掉的情况补上)
而1又等于\((-1)^0*\binom{k}{0}\)
所以原式就变成了\((-1)^0*\binom{k}{0}+(-1)^1*\binom{k}{1}+(-1)^2*\binom{k}{2}+...+(-1)^k*\binom{k}{k}\)
没有感到这个式子很熟悉?
不熟悉去找数学老师跪搓衣板
二项式定理:\((a-b)^k = \binom{k}{0}a^k*b^0+\binom{k}{1}a^{k-1}*b^1+...+\binom{k}{k}a^0*b^k\)
所以原式就等于\((1-1)^k\) 即0
(由第一条性质知当且仅当\(gcd(i,j)=1\)时后面的和式有值,所以成立
将d提前
后面的枚举空循环显然是没有意义的
所以化为
然后两边同除\(n\) 得到
原式得证
另一种证明:
由狄利克雷卷积\(\varphi = id*\mu\)
得到\(\varphi(n)=\sum_{d|n}\mu(d)\cdot \frac{n}{d}\)
两边同时处理n 得到原式
筛法比筛一般的积性函数还要简单一点
void sieve(){
mu[1] = 1;
for(int i = 2;i <= maxk - 5;++i) {
if(!vis[i]) prime[++cnt] = i,mu[i] = -1;
for(int j = 1;j <= cnt && prime[j] * i <= maxk - 5;++j) {
vis[prime[j]*i] = 1;
mu[i*prime[j]] = -mu[i];
if(i % prime[j] == 0) {mu[i*prime[j]] = 0;break;}
}
}
}
莫比乌斯反演
前提:\(f()\)是积性函数
证明:
关于最后一步:
首先由性质1知 当\(d != n\) 时 答案为0
所以只需要统计当\(d = n\)时的答案
所以最后得到\(f(n)\)
另一种形式:
题
A:P2257 YY的GCD
题目求\(gcd(i,j) \epsilon prime\)的个数
写成柿子
一般套路,\(gcd(i,j) = 1\) 可以化成\(\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} \sum\limits_{d|gcd(i,j)}\mu{(d)}\)
原因很显然
由莫比乌斯函数性质一:\(\sum\limits_{d|n}\mu{(d)} = [n = 1]\)
把\(gcd(i,j)\)代入n就好了
而该题要求的是gcd为素数的
所以想到可以枚举素数 然后套式子
假设此时的gcd(i,j) = k
则答案变为\(\sum\limits_{k=1}^{n} \sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} gcd(i,j)=k\)
此时k一定满足\(k|i,k|j\)
也就是\(\sum\limits_{k=1}^{n} \sum\limits_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor} \sum\limits_{j=1}^{\left \lfloor \frac{m}{k} \right \rfloor} \sum\limits_{d|gcd(i,j)}\mu{(d)}\)
发现可以把d提前 然后就变成了\(\sum\limits_{k=1}^{n} \sum\limits_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor} \sum\limits_{i=1}^{\left \lfloor \frac{n}{k*d} \right \rfloor} \sum\limits_{j=1}^{\left \lfloor \frac{m}{k*d} \right \rfloor} \mu{(d)}\)
此时i和j这两维显然就没用了 因为后面的\(\mu{(d)}\)与i,j无关
直接去掉 把加法改成乘法就好了
\(\sum\limits_{k=1}^{n} \sum\limits_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\left \lfloor \frac{n}{k*d} \right \rfloor*\left \lfloor \frac{m}{k*d} \right \rfloor*\mu{(d)}\)
然后我们的60分就到手了
现在考虑优化这个式子
设T = k*d
那么有原式等于\(\sum\limits_{k=1}^{n} \sum\limits_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\left \lfloor \frac{n}{T} \right \rfloor*\left \lfloor \frac{m}{T} \right \rfloor*\mu{(d)}\)
发现此时的T可以提前
所以原式就变为了\(\sum\limits_{T=1}^{n} \left \lfloor \frac{n}{T} \right \rfloor*\left \lfloor \frac{m}{T} \right \rfloor \sum\limits_{k|T,k \epsilon prime}\mu{(\frac{T}{k})}\)
发现\(\sum\limits_{k|T,k \epsilon prime}\mu{(\frac{T}{k})}\) 是可以预处理的
只要计算一个\(\mu{(d)}\)时,把它所有倍数T 都加上一个对应的贡献\(\mu{(\frac{T}{d})}\)就可以了
计算前缀和 方便整除分块的时候快速计算贡献
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7 + 10;
int prime[maxn];
int vis[maxn];
int mu[maxn];
int cnt;
int f[maxn];
ll sum[maxn];
void init(){
mu[1] = 1;
for(int i = 2;i <= maxn - 5;++i) {
if(!vis[i]) vis[i] = 1,prime[++cnt] = i,mu[i] = -1;
for(int j = 1;j <= cnt && prime[j] * i <= maxn - 5;++j) {
vis[i*prime[j]] = 1;
if(i % prime[j] == 0) break;
mu[i*prime[j]] = -mu[i];
}
}
for(int i = 1;i <= cnt;++i)
for(int j = 1;j <= maxn && prime[i] * j <= maxn - 5;++j)
f[j*prime[i]] += mu[j];
for(int i = 1;i <= maxn - 5;++i) sum[i] = sum[i-1] + f[i];
}
int main(){
init();
int T;scanf("%d",&T);
while(T--) {
int n,m; scanf("%d%d",&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 += (sum[r] - sum[l-1]) * (n / l) * (m / l);
}
printf("%lld\n",ans);
}
return 0;
}
B: P3327 约数个数和
\(\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} d(ij)\)
难点显然在于如何转化\(d(ij)\)
\(d(ij)\)可以化成\(\sum\limits_{x|i}^{i} \sum\limits_{y|j}^{j} [gcd(x,y)=1]\) 的形式
考虑\(ij\)的每个因子 对于每个每个因子一定可以划分成\({p_1}^{c1}*{p_2}^{c2}*...\)
规定每个指数首先从i中选 i中不够再从j中选 这样每个因子一定可以找到唯一的一种划分 而每一种划分一定可以对应唯一的因子
而对于\(\sum\limits_{x|i}^{i} \sum\limits_{y|j}^{j} [gcd(x,y)=1]\)
首先\(x*y\)一定是\(i*j\)的因子
\(gcd(x,y) = 1\) 说明x与y不含有相同的质因子
考虑划分规则 对于\(x=1,y=2\)和\(x=2,y=1\) 此时构造出来的因子并不相同 因为y有值的条件是 x已经选完
所以\(y=2\)时表示 构造出一个\(i\)中所有的质因子2都选 \(j\)中选了一个 而\(y=1\)时显然不同 所以不会重复
而因为每一个因子都可以用这样的方法构造出来 所以不会漏掉情况
然后就是一般的莫比乌斯反演了
将式子代入可得\(\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} \sum\limits_{x|i} \sum\limits_{y|j} [gcd(x,y)=1]\)
将\(x,y\)提前 得到
\(\sum\limits_{x=1}^{n} \sum\limits_{y=1}^{m} \sum\limits_{i|x} \sum\limits_{j|y} [gcd(i,j)=1]\)
显然后面的枚举可以省掉 得到
\(\sum\limits_{x=1}^{n} \sum\limits_{y=1}^{m} \left \lfloor n/x \right \rfloor \left \lfloor m / y \right \rfloor [gcd(i,j)=1]\)
设\(f(x) = \sum\limits_{x=1}^{n} \sum\limits_{y=1}^{m} \left \lfloor n/x \right \rfloor \left \lfloor m / y \right \rfloor [gcd(i,j)=x]\)
\(g(x) = \sum\limits_{x|d} f(d)\)
\(g(x) = \sum\limits_{x|d} \sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} \left \lfloor n/i \right \rfloor \left \lfloor m / j \right \rfloor [gcd(i,j)=d]\)
发现第一维的枚举可以省掉 变为
\(g(x) = \sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} \left \lfloor n/i \right \rfloor \left \lfloor m / j \right \rfloor [x|gcd(i,j)]\)
将gcd消除 得
\(g(x) = \sum\limits_{i=1}^{\frac{n}{x}} \sum\limits_{j=1}^{\frac{m}{x}} \left \lfloor n/ix \right \rfloor \left \lfloor m/jx \right \rfloor\)
然后移项得到
\(g(x) = \sum\limits_{i=1}^{\frac{n}{x}} \left \lfloor n / ix \right \rfloor \sum\limits_{j=1}^{\frac{m}{x}} \left \lfloor m/jx \right \rfloor\)
预处理出\(f(x) = \sum\limits_{i=1}^{x}\left \lfloor x/i \right \rfloor\)
然后就可以O(1)计算g函数了
又有\(f(x) = \sum\limits_{x|d} \mu(d/x) g(d)\)
则\(f(1) = \sum\limits_{i=1}^{n} \mu(i) g(i)\)
\(f(1) = \sum\limits_{x=1}^{n} \mu(x)\sum\limits_{i=1}^{\frac{n}{x}} \left \lfloor n / ix \right \rfloor \sum\limits_{j=1}^{\frac{m}{x}} \left \lfloor m/jx \right \rfloor\)
后面的部分可以整除分块优化成根号
C:P4449 于神之怒加强版
(假定\(n <= m\))
首先原式可以化为
\(\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} \sum\limits_{d=1}^{n} [gcd(i,j)=d] * d^k\)
移项 得
\(\sum\limits_{d=1}^{n} d^k \sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} [gcd(i,j)=d]\)
即
\(\sum\limits_{d=1}^{n} d^k \sum\limits_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\sum\limits_{j=1}^{\left \lfloor \frac{m}{d} \right \rfloor}[gcd(i,j)=1]\)
一般套路将gcd消除得到
\(\sum\limits_{d=1}^{n} d^k \sum\limits_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\sum\limits_{j=1}^{\left \lfloor \frac{m}{d} \right \rfloor}\sum\limits_{k|gcd(i,j)} \mu(k)\)
将k提前 得
\(\sum\limits_{d=1}^{n} d^k \sum\limits_{k=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \sum\limits_{i=1}^{\left \lfloor \frac{n}{dk} \right \rfloor}\sum\limits_{j=1}^{\left \lfloor \frac{m}{dk} \right \rfloor} \mu(k)\)
发现后面的式子跟\(i,j\)没有关系 ,即
\(\sum\limits_{d=1}^{n} d^k \sum\limits_{k=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \left \lfloor \frac{n}{dk} \right \rfloor \left \lfloor \frac{m}{dk} \right \rfloor \mu(k)\)
令\(T=dk\)
有
\(\sum\limits_{d=1}^{n}d^k \sum\limits_{k=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor \mu(k)\)
将枚举d改为枚举T 有
\(\sum\limits_{T=1}^{n} \left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor \sum\limits_{d|T}\mu(\frac{T}{k}) * d^k\)
发现后面的部分可以预处理
令\(g(x) = \sum\limits_{d|x}\mu(\frac{x}{k}) * d^k\)
则\(g(x)\)为积性函数
所以可以线性筛把\(g()\)函数筛出来
一个质数\(p\)的函数值可以算出 等于\(p^k-1\)
考虑\(g[i*prime[j]]\) 如果\(i\)与\(prime[j]\)互质 显然可以直接乘起来 得到函数值
如果\(i\) % \(prime[j] != 0\)时 考虑如何快速求出函数值
发现\(i\)一定可以表示为\({p_1}^{c_1}*{p_2}^{c2}*...\)
乘\(prime[j]\)后一定是 \({p_1}^{c_1+1} * {p_2}^{c2} * ...\)
后面的部分完全一样
所以考虑如何计算前面的部分
因为\(g[i*prime[j]] = g[i] / g[{p_1}^{c1}] * g[{p_1}^{c1+1}]\)
对于后面的部分 等于
\(\sum\limits_{d|{p_1}^{c_1+1}}\mu(\frac{{p_1}^{c_1+1}}{d}) * d^k\)
由\(\mu\)函数定义可知 只有当\(d\)取\({p_1}^{c_1+1}\) 或者 \({p_1}^{c_1}\) 时 \(\mu\)值不为0
得到\(g[{p_1}^{c1+1}] = {{p_1}^{(c_1+1)}}^k - {{p_1}^{c_1}}^k = {{p_1}^{c_1}}^k *( {p_1}^{k} - 1)\)
而\(g[{p_1}^{c1}] = {{p_1}^{c_1}}^k - {{p_1}^{(c_1-1)}}^k = {{p_1}^{(c_1-1)}}^k *( {p_1}^{k} - 1)\)
所以\(g[{p_1}^{c1+1}] = g[{p_1}^{c1}] * {p_1}^k\)
所以就可以线性筛了
筛完之后 处理一下前缀和 然后整除分块就可以了
D:jzptab
很套路的题
\(\sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j)\)
\(\sum_{i=1}^{n}\sum_{j=1}^{m}\frac{ij}{gcd(i,j)}\)
枚举gcd
\(\sum_{d=1}^{n}\frac{1}{d}\sum_{i=1}^{n}\sum_{j=1}^{m} ij*[(i,j)=d]\)
\(\sum_{d=1}^{n}\frac{1}{d}\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}} ij*d^2*[(i,j)=1]\)
发现\(d^2\)可以提前 得到
\(\sum_{d=1}^{n} d\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}} ij*[(i,j)=1]\)
把\([(i,j)=1]\) 展开
\(\sum_{d=1}^{n} d\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}} ij \sum_{k|gcd(i,j)} \mu(k)\)
交换枚举顺序
\(\sum_{d=1}^{n} d \sum_{k=1}^{\frac{n}{d}}\mu(k) \sum_{i=1}^{\frac{n}{dk}}\sum_{j=1}^{\frac{m}{dk}} ij*k^2\)
\(k^2\) 提前得到
\(\sum_{d=1}^{n} d \sum_{k=1}^{\frac{n}{d}}k^2\mu(k) \sum_{i=1}^{\frac{n}{dk}}\sum_{j=1}^{\frac{m}{dk}} ij\)
Solution1:
到这里已经可以过掉洛谷的数据了 单组询问,时限2s
\(\sum_{i=1}^{\frac{n}{dk}}\sum_{j=1}^{\frac{m}{dk}} ij\) 就是两个等差数列乘起来
所以可以用整除分块做到根号复杂度
发现对于n来说,\(\sum_{k=1}^{\frac{n}{d}}k^2\mu(k)\) 也可以整除分块处理
所以两个整除分块处理 O(n)预处理 O(\(n^\frac{3}{4}\))回答每次询问
Solution2:
但是另一个数据范围是时限8s,1e4组询问
上面的式子可以继续化简
设\(T = dk\)
\(\sum_{T=1}^{n} \sum_{k|T} k^2\mu(k)*\frac{T}{k}\sum_{i=1}^{\frac{n}{T}} \sum_{j=1}^{\frac{m}{T}}ij\)
中间的部分可以\(nln\)预处理 后面的部分可以整除分块
一个小trick是当\(\mu(i)=0\)时直接跳过,可以减小一半常数
然后就可以做到\(O(nln)\)预处理 \(O(\sqrt{n})\)处理单组询问
Solution3:
但是我们可以做到更优秀的时间复杂度
复杂度瓶颈显然在预处理 考虑怎么优化这个过程
发现可以把原式再化一下变成
\(\sum_{T=1}^{n} T\sum_{k|T} k*\mu(k)\sum_{i=1}^{\frac{n}{T}} \sum_{j=1}^{\frac{m}{T}}ij\)
令\(F[n] = \sum_{k|n} k * \mu(k)\)
然后发现中间的式子就是个积性函数
关于为什么是积性函数 两个积性函数对位相乘显然是积性函数
而\(id\) 跟 \(\mu\) 都是积性函数 所以这东西也是积性函数
然后就可以线性筛了
只需要考虑特殊情况:
p为质数 \(F[p] = 1 - p\)
\(p^k\) 考虑原式,只有当因子等于\(1\)或p时\(\mu\)值不为0
所以\(F[p^k] = 1-p\)
\(low[i]\) 表示i的\(p_1^{c1}\) 即i最小质因子的贡献
所以\(F[i*prime[j]] = F[i/low[i]] * F[low[i]*prime[j]]\)
\(low[i]*prime[j]\) 一定是\(p^k\) 的形式
所以\(F[i*prime[j]] = F[i/low[i]] *F[low[i]] = F[i]\)
所以就可以线性筛了
Solution4:
还是考虑优化预处理的部分
发现中间的式子完全就是狄利克雷前缀和的模板 然后就可以做了
E: 数表
需要一点点小转化 之前没有见过这种套路记录一下
首先不考虑a的限制
令\(f[i]\)表示i的约数和
列出式子
求 $\sum_{i=1}^{n} \sum_{j=1}^{m} f[gcd(i,j)] $
简单化一下有
\(\sum_{d=1}^{n} \sum_{i=1}^{n} \sum_{j=1}^{m} f[d] * [gcd(i,j)=d]\)
很显然的式子了 推过好多遍的 直接到终态
\(\sum_{T=1}^{n}\sum_{d|T}f(d)\mu(\frac{T}{d}) \left \lfloor \frac{n}{T} \right \rfloor\left \lfloor \frac{m}{T} \right \rfloor\)
如果没有a的限制我们到这里就做完了
考虑有a的限制怎么办
a的限制是对于\(f(d)\)的
所以可以对于\(f(d)\)按照权值排序
对于询问按照a排序
每次暴力加入一些新的\(f(d)\) 并更新前缀和
然后整除分块回答询问
更新前缀和可以套一个树状数组 就很方便了
一共会更新\(nln\)次答案,每次更新答案复杂度为\(log\) 所以修改总复杂度为\(nln*log\)
每次回答询问是\(O(\sqrt{n})\)
F:数字表格
挺新的套路
\(\prod_{i=1}^{n} \prod_{j=1}^{m}f[gcd(i,j)]\)
这个题不同的地方在于变成了乘法,先化式子
\(\prod_{d=1}^{n}\prod_{i=1}^{n} \prod_{j=1}^{m} f[d]^{[gcd(i,j)=d]}\)
连乘可以放到指数上去 所以
\(\prod_{d=1}^{n}f[d]^{\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=d]}\)
一般套路
\(\prod_{d=1}^{n}f[d]^{\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}[gcd(i,j)=1]}\)
\(\prod_{d=1}^{n}f[d]^{\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}\sum_{k|gcd(i,j)}\mu(k)}\)
\(\prod_{d=1}^{n}f[d]^{\sum_{k=1}^{\frac{n}{d}} \mu(k) \sum_{i=1}^{\frac{n}{dk}}\sum_{j=1}^{\frac{m}{dk}}}\)
然后把k放到外边
\(\prod_{d=1}^{n}\prod_{k=1}^{\frac{n}{d}}f[d]^{ \mu(k) \sum_{i=1}^{\frac{n}{dk}}\sum_{j=1}^{\frac{m}{dk}}}\)
令T=dk
改为枚举T, 原式变为
\(\prod_{T=1}^{n}\prod_{d|T} f(d)^{\mu(\frac{T}{d})\frac{n}{T}\frac{m}{T}}\)
原式等于\(\prod_{T=1}^{n}(\prod_{d|T} f(d)^{\mu(\frac{T}{d})})^{\frac{n}{T}\frac{m}{T}}\)
外面的部分显然可以整除分块 , 里面的部分直接暴力就可以了
G:DZY Loves Math
求 \(\sum_{i=1}^{n}\sum_{j=1}^{m}f(gcd(i,j))\)
\(\sum_{d=1}^{n}f(d)\sum_{k=1}^{\frac{n}{d}}\mu(k)\sum_{i=1}^{\frac{n}{dk}}\sum_{j=1}^{\frac{m}{dk}}\) (中间的步骤都是套路就直接跳过了)
令T=dk
\(\sum_{T=1}^{n} \sum_{d|T}f(d)\mu(\frac{T}{d})\frac{n}{dk}\frac{m}{dk}\)
显然重点在于把中间的部分处理掉
令\(g(T) = \sum_{d|T}f(d)\mu(\frac{T}{d})\)
考虑怎么求这个函数
首先我们要求的一定是\(\mu\)值不为0的项
将T分解为\(p_1^{a_1}*p_2^{a_2}*...*p_k^{a_k}\)
将d分解后
我们选择的\(cnt_i\)一定满足\(a_i-1 <= cnt_i <= a_i\) 这样的项才会对答案造成贡献
而考虑存在\(i,j\)其中\(a_i<a_j\) 那么此时这个\(g(T)\)一定为0
因为选或者不选i ,对于答案是没有影响的(\(f\)函数的定义)
而选i与不选i时的\(\mu\)值是恰好互为相反数的,所以这样的项对答案的贡献为0
而当所有\(a_i = a_j\)时,我们可以假设此时所有的f值都等于\(a_i\)
那么这时候的根据刚刚的思路 可以把所有数分成两部分 一部分是选到\(a_i\)的 ,另一部分是选到\(a_i-1\)的
第二部分选到奇数个与偶数个的方案数显然是相等的 所以答案仍是0
但是当选的所有的都为\(a_i-1\)时,此时答案为\(a_i-1\) 并不是我们设的\(a_i\)
所以要把这个\(-1\)的贡献算上 , 此时贡献就是\((-1)^{k+1}\)
然后转移就很显然了