Möbius 反演注记
2021 年写的:数论基础模板库(不保证正确性) ; Mobius 反演(内含 \(\mu\) 作容斥系数)
基本理论基础
规定素数集记做 \(\mathbb P\) .
\(\gcd(i,j)=1\) 可以记做 \(i\perp j\) .
数论函数
数论函数是定义域为 \(\mathbb N\),陪域为 \(\mathbb C\) 的函数 .
注意重点是定义域为 \(\mathbb N\) .
线性筛
理论上任何积性函数都可以线性筛,线性筛需要:
- 素数处的取值
- \(q\) 是 \(p\) 的最小素因子,已知 \(f(p),f(q)\),求 \(f(pq)\) .
一般应用:筛素数,筛 \(\varphi\),筛 \(\mu\),筛 \(\sigma_k\) .
实际上基于质因数分解可以只用素数处的取值求出所有取值(例:固定指数幂) .
拉一份淳朴的板子过来(筛素数,欧拉函数和 Mobius 函数)
bool notprime[N];
int phi[N], mu[N];
vector<int> plist;
inline void linear_sieve(int n)
{
notprime[1] = true; phi[1] = mu[1] =1 ;
for (int i=2; i<=n; i++)
{
if (!notprime[i]){plist.emplace_back(i); phi[i] = i-1; mu[i] = -1;}
for (auto x : plist)
{
int now = i*x;
if (now > n) break;
notprime[now] = true;
if (!(i%x)){phi[now] = phi[i] * x; mu[now] = 0; break;}
else{phi[now] = phi[i] * phi[x]; mu[now] = mu[i] * mu[x];}
}
}
}
Mobius 反演
Möbius 太难写了,不如写 Mobius .
既然这篇叫莫比乌斯反演,我们就默认大家都会莫比乌斯反演了 .
复习一下:
Dirichlet 卷积的莫比乌斯反演:
特殊形式:
- 标准型:\(\displaystyle f(n)=\sum_{d\mid n}g(d) \Longleftrightarrow g(n)=\sum_{d\mid n}f\left(\dfrac nd\right)\mu(d)\) .
- 直接推论:\(\displaystyle f(n)=\sum_{d=1}^{\left\lfloor\tfrac Tn\right\rfloor}g(di) \Longleftrightarrow g(n)=\sum_{d=1}^{\left\lfloor\tfrac Tn\right\rfloor}f(di)\mu(d)\),\(T\) 是常数 .
Dirichlet 卷积
我们一般见到的 Dirichlet 卷积是不是这样的:
但多项式技术中卷积一般是不是长这样
\(h\) 就是 \(f,g\) 的卷积,然后 \(\circ\) 是随便一个运算,特殊形式:
- 如果 \(\circ\) 是加,那么就是通常意义上的 卷积 .
- 如果 \(\circ\) 是位运算,那么就是一般叫的 位运算卷积 .
- 如果 \(\circ\) 是乘,然而 \(f,g\) 是数论函数(定义域为 \(\mathbb N\)),所以 \(i,j\) 必然是整数,这就是我们通常意义上的 Dirichlet 卷积 .
写下来这个形式:
其中 \(i,j\) 都是整数 .
交换律,结合律不言自明 .
常见卷积:
- \(\mu*1=\varepsilon\)(即 \(\mu\) 是 \(1\) 的 Dirichlet 卷积逆)
- \(\varphi*1=\mathrm{id}\)(欧拉反演) .
- \(\mu*\mathrm{id}=\varphi\) .
你看第一个东西,Mobius 反演是不是那个玩意的直接推论?(\(f=g*1\) 两边同时卷 \(\mu\)).
Dirichlet 卷积的计算:枚举因子然后累加贡献,\(O(n\log n)\) .
然而 Dirichlet 卷积是不是卷积啊,我们普通卷积有 FFT,位运算卷积有 FMT/FWT,然而 Dirichlet 卷积有没有一个幸运函数使得满足卷积定理呢?
其实是有的,可以了解一些 贝尔级数 / 狄利克雷生成函数 相关知识,限于篇幅 & 笔者能力这里就不说了 .
数论分块 / 整除分块
整除只有根号种本质不同的取值,于是可以压到一起 .
就比如你算一个 \(\displaystyle\sum_{i=1}^n\left\lfloor\dfrac ni\right\rfloor F(i)\),代码大概长这样:
ll Koishi(int n)
{
ll ans = 0;
int l=1, r;
while (l <= n)
{
r = n / (n / l);
ans += (F(r) - F(l-1)) * (n / l);
l = r + 1;
} return ans;
}
上面是拉的 OI Wiki 上的,实际上可以写 for
循环 .
然后多维整除分块只需要取 \(\min\),具体找个人的贺下来就好了 .
如果 \(F\) 可以 \(O(1)\) 计算,那么复杂度 \(O(\sqrt n)\),即 \(O(n^{1/2})\) .
注意算复杂度不能把 \(O(n^{1/2})\) 直接乘上算 \(F\) 的复杂度,整除分块的复杂度是比较难分析的,反正我不会 .
特殊:
- 整除分块套杜教筛:\(O(n^{2/3})\) .
- 整除分块套整除分块:\(O(n^{3/4})\) .
拆函数
贺的 APJ 的 .
对于任何 \(i,j\) 都成立,不管互不互素 .
时间复杂度分析
基本形式
GCD 形
求
\[\sum_{i=1}^n\sum_{j=1}^mg(\gcd(i,j)) \]
设函数 \(f\) 使得 \(f*1=g\) .
一些基本推导:
整除分块,要求 \(f\) 可以快速求前缀和 .
根据 Mobius 反演,我们把 \(g\) 卷上 \(\mu\) 就是 \(f\) 了,可以 \(O(n\log n)\) .
如果空间不够,那么因为这个卷积的形式可以杜教筛求前缀和(当然整除分块套杜教筛是 \(O(n^{2/3})\) 的,比卷出来劣)
然而展开 \(f=g*\mu\) 然后交换两个 \(\sum\) 就可以 Dirichlet 后缀和 做到 \(O(n\log\log n)\) .
也有一种 非常牛逼的做法 可以直接 \(O(n\log\log n)\) 卷 .
这个可以推广到 \(f*g=h\) 形,但是没啥用,大概可以推出来整除分块套杜教筛或者三个整除分块套起来的形式,读者可以试试 .
这个是不是可以轻易推广到多个 \(\sum\) .
GCD 形其实非常常见 .
- YY的GCD:\(g(n)=[n\in\mathbb P]\)(需要开
-O2
) . - 数表:\(g(n)=d(n)[d(n)\le a]\)(不能直接用上面的做法(杜教筛或许能过?没写过 QwQ)).
- 于神之怒加强版:\(g(n)=n^k\) .
万能
求
\[\sum_{i=1}^n\sum_{j=1}^mf(i)g(j)h(\gcd(i,j)) \]
https://www.luogu.com.cn/blog/qwaszx/ru-men-fan-yan-tao-lu
这个牛逼东西看到的比较晚 QwQ .
一大堆题都是长个样子 .
Prod 的莫比乌斯反演
来源 .
定义 \(\displaystyle(f\oplus g)(n) = \prod_{d\mid n}f(d)^{g(\frac nd)}\) .
则有 \((f \oplus g) \oplus h = f \oplus (g * h)\),其中 \(*\) 是 Dirichlet 卷积
(?)
然后就可以得到 \(f=g\oplus 1\Longleftrightarrow g=f\oplus\mu\) .
注意 \(\oplus\) 没有交换律
然后该咋做咋做,GCD 形啥的都可以套 .
预处理幂,这个卷也可以 \(O(n\log n)\) 算 .
然而 Prod 的整除分块有些变化,注意 .
正常例题
省略:数据范围、模数 .
不加注释的技法:
- 基本形式
- 按定义拆函数
- 按常见卷积拆函数(例如 \(\displaystyle n=\sum_{d\mid n}\varphi(d)\),\(\displaystyle [n=1]=\sum_{d\mid n}\mu(d)\))
- 加一个 \(\sum\) 枚举某个变量(一般是 \(\gcd\))
- 交换求和号
- 小学就学过的平凡算术 .
YY 的 GCD
求
\[\sum_{i=1}^n\sum_{j=1}^n[\gcd(i,j)\in\mathbb P] \]
GCD 形,函数 \(p(x)=[x\in\mathbb P]\) 可以线性筛,暴力卷 \(\mu\) 即可 .
数表
令 \(f(x)=[\sigma_1(c)\le a]\sigma_1(c)\),求
\[\sum_{i=1}^n\sum_{j=1}^nf(\gcd(i,j)) \]每次询问给一个 \(a\) .
假设没有 \(a\) 的限制,那么我们要求的就是
GCD 形,令 \(g=\sigma_1*\mu\),那么原式变成
注意这里是要求 \(g\) 可以快速求前缀和 .
牛逼的地方来了 .
然后因为有 \(a\) 这个限制,所以考虑把询问离线下来,然后排序叠加贡献 .
你看这个 \(g\) 的形式是不是 \(\displaystyle g(n)=\sum_{d\mid n}\sigma_1(d)\mu\left(\dfrac n{d}\right)\),因为我们限制的是 \(\sigma_1(d)\) 的值,所以用一个指针跳就好了 .
相当于单点加,前缀和,可以树状数组,没了 .
details: 因为取模 \(2^{31}\) 所以可以 int
自然溢出最后按位与 \(2^{31}-1\)(此处是 UB,但是确实好用)
DZY Loves Math
定义 \(f(n)\) 为 \(n\) 所含质因子的最大幂指数,求
\[\sum_{i=1}^n\sum_{j=1}^n f(\gcd(i,j)) \]
GCD 形,然而暴力卷会 TLE……吗?
开个 -O2
直接过了?????
?????????????????
有正经做法推出来一个 \(f*\mu\) 的通项,不懂 .
约数个数和
求
\[\sum_{i=1}^n\sum_{j=1}^md(ij) \]
因为是当草稿写的,可能有冗余 .
不妨令 \(n\le m\) 吧 .
一些平凡的转化,用到的都是基本 Trick .
发现要处理后面那个玩意了,令 \(\displaystyle F(d)=\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac md\rfloor}\left\lfloor\dfrac n{id}\right\rfloor\left\lfloor\dfrac m{jd}\right\rfloor\) .
然后发现 \(i,j\) 差不多是独立的,于是可以提出来:
(当然这里下标比较无聊,你愿意改成 \(i\) 也行)
于是原式就类似 \(\displaystyle\sum_{i=1}^n P(i)Q\left(\left\lfloor\dfrac ni\right\rfloor\right)R\left(\left\lfloor\dfrac mi\right\rfloor\right)\) 这种形式,整除分块即可 .
然而整除分块套整除分块是 \(O(n^{3/4})\) 的,于是复杂度是 \(O(Tn^{3/4})\),算出来大概是 1.5e8 .
数字表格
求
\[\prod_{i=1}^n\prod_{j=1}^mF_{\gcd(i,j)} \]\(F\) 是 Fibonacci 数列 .
先 \(\ln\) 再 \(\exp\),取底数 \(=2\) 做 BSGS .
Prod 形的 GCD .
于神之怒加强版
求
\[\sum_{i=1}^n\sum_{j=1}^m(\gcd(i,j))^k \]
GCD 形 .
线性筛是啥玩意?难道不是暴力就完了吗??
\(O(n\log\log n+T\sqrt n)\) .
jzptab
求
\[\sum_{i=1}^n\sum_{j=1}^m\operatorname{lcm}(i,j) \]
花了大概一个公共自习推出来力 /cy .
不妨令 \(n\le m\) .
其中 \(\displaystyle S(x)=\sum_{i=1}^xi=\dfrac{x(x+1)}2\) .
用到了一个小结论:\(\Big\lfloor\dfrac{\lfloor\frac{n}{p}\rfloor}{q}\Big\rfloor = \Big\lfloor\dfrac{n}{pq}\Big\rfloor\),About it .
然后后面可以线性预处理,\(O(Tn^{1/2})\) .
模数是 1e8+9!!!模数是 1e8+9!!!模数是 1e8+9!!!模数是 1e8+9!!!模数是 1e8+9!!!
一个人的数论
给定 \(n,k\),求
\[f_k(n)=\sum_{i=1}^n[\gcd(i,n)=1]i^k \]对 \(10^9+7\) 取模 .
数据范围及输入细节见 原题面 .
首先平凡莫反:
然后后面是不是自然数幂和?众所周知这玩意是 \(k+1\) 次多项式,设 \(p\) 次项系数为 \(F_p\),这个玩意咋求后面再说 .
于是可以继续化
后面显然就是 \(1*(\mu\cdot\mathrm{Id}_{n-i})\),必然是积性函数 .
然后因为给出的质因数分解式,所以我们可以暴力求出所有素数幂处的取值然后乘起来即可 .
然而 \(\mu\) 接收到平方因子就变成 \(0\) 了,于是只需求出素数处取值,暴力即可 .
然后前面的 \(n\) 可以直接对 \(10^9+7\) 取模 .
现在来说说 \(F\) 怎么求 .
如果你插值你就 naive 了,因为插值最快 \(O(k\log^2k)\),如果写最 simple 的拉格朗日插值还是 \(O(k^2)\) 的 .
我们可以用伯努利数求这个玩意,完全可以做到 \(O(k\log k)\),只需要一次求逆!!!
然而模数是 \(10^9+7\),求逆会瞬间变得巨大多难写 . 但是递推伯努利数也比插值不知道高到哪里去了 .
似乎 \({O(k^3)}\) 高斯消元能过
以下是博客签名,正文无关
本文来自博客园,作者:Jijidawang,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/16081115.html
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ