浅述狄利克雷卷积,莫比乌斯函数,莫比乌斯反演
前言
- TTC讲的太好了全听懂了呢谢谢你喵~/bx
- upd on 8.15 16:25:添加证明
卷积
- 相当于莫反的前置芝士了,我们讲狄利克雷卷积
- 先说个概念:
- 数论函数:定义域为 \(Z^+\) 的函数
- 那对于两个数论函数 \(f\) 和 \(g\),我们有
\[h(n) = \sum\limits_{d|n}{f(n) \times g({n \over d})}
\]
- 这个运算叫做卷积运算,简称卷,符号为 \(\ast\),上面的运算记为 \(h = f \ast g\)
- 这个运算都叫卷积了,他和正常的积运算一样满足交换律,结合律,分配率
- 还有一个性质,是证莫反的过程需要的,但是我们要先说三个新概念
\[I = <1,1,1,\dots>
\]
\[I_d = <1,2,3,\dots>
\]
\[\epsilon = <1,0,0,\dots>
\]
- 其中 \(I\) 称为常数函数,\(I_d\) 称为恒等函数,\(\epsilon\) 是希腊字母,读作 \(epsilon\),为单位函数(欸这个常数函数符号是 \(I\) 还是 \(1\) a,算了写错会有人说的)
- 那会有一个性质:
\[f = f \ast \epsilon
\]
- 可以徒手算一下
- 其实卷积也可以做求逆的运算,msjing不会就先不说了
- 还有一个定义,一并介绍了
积性函数:
- 定义一个数论函数 \(f(x)\),如果 \(f(x) \times f(y) = f(x \times y)\) \((gcd(x,y) = 1)\),则称 \(f(x)\) 为积性函数
- 广义的积性函数就是把互质的限制去掉
- 比如欧拉函数 \(\varphi (x)\) 和要说的莫比乌斯函数 \(\mu (x)\) 都是积性函数
莫比乌斯函数
- 莫比乌斯函数记作 \(\mu (x)\),有以下定义
\[ \mu (n)=\begin{cases}
1 & (n=1)\\
(-1)^k & (n = p_1^1 + p_2^1 + \dots + p_k^1)\\
0 & (else)
\end{cases} \]
- 形象地,当 \(n = 1\) 时,\(\mu (n) = 1\);当 \(n\) 的所有质因数只出现了一次时:若有奇数个质因数,\(\mu (n) = -1\),若有偶数个质因数,\(\mu (n) = 1\);若质因数有相同的,\(\mu (n) = 0\)
- 我们就知道了莫比乌斯函数了,求的话可以用欧拉筛(线性筛)直接求,实现给一下吧
点击查看代码
void init(int n)
{
mo[1]=1;
for (int i=2;i<=n;i++)
{
if (!is_no_p[i]) prime[++prime[0]]=i,mo[i]=-1;
for (int j=1;j<=prime[0] && i*prime[j]<=n;j++)
{
is_no_p[i*prime[j]]=1;
if (i%prime[j] == 0) {mo[i*prime[j]]=0;break;}
mo[i*prime[j]]=mo[i]*(-1);
}
}
}
- 好像是这个,有锅来找sbmqwm
- sbmqwm:?
- msjing:总有一种不好的预感
- 接下来介绍性质,有一个重要的性质,是推莫反的基础
\[\sum\limits_{d|n}{\mu (d) = [n = 1]}
\]
证明
- 对于 $ \sum\limits_{d|n}{\mu (d)} $,我们把 \(\mu (d)\) 改为 \(\mu (\left\lfloor\dfrac nd\right\rfloor)\),这个显然,因为你怎么枚举约数都一样,原式变成:
\[\sum\limits_{d|n}{\mu (\left\lfloor\dfrac nd\right\rfloor)}
\]
- 对 \(n\) 分解质因数,根据算数基本定理,有:
\[n = p_1^{c_1} + p_2^{c_2} + \dots + p_k^{c_k}
\]
- 我们任取一些 \(p\),其中对应的 \(c\ne1\) 对答案没贡献,不管,我们直接尝试枚举约数,原式变成:
\[\sum\limits_{i=0}^{k}\binom{k}{i}(-1)^i
\]
- 我们直接用二项式定理转化,不会看看这里,原式变为:
\[(1-1)^k
\]
- 即:
\[0^k
\]
- 当 \(k=0\) 即 \(n=1\) 时,原式为 \(1\),其余情况为 \(0\),得证
好像证毕还可以用QED
- 其中的 \([n = 1]\) 可以理解为 C++ 的
n == 1,成立返回 \(1\),否则返回 \(0\) - 我们还可以扩展一下,把 \(n\) 改为 \(\gcd(i,j)\)(你发现任意一个 \(n\) 都可以用两个数的 \(\gcd\) 表示)
- 那就会有:
\[[\gcd(i,j) = 1] = \sum\limits_{d|\gcd(i,j)}{\mu (d)}
\]
- 这个东西可以写为:
\[\sum\limits_{d}{[d|i] \times [d|j] \times \mu (d)}
\]
- 这样的话就把互质和莫比乌斯函数联系起来了
- 还有一个性质:
\[I \ast \mu = \epsilon
\]
- 这个也是证莫反的关键
莫比乌斯反演
- 这个东西挺简单,但是这个东西用起来就是个东西
- 好!(激情)我们开始介绍莫反
- 莫比乌斯反演和二反差不多(?),都是两个柿子知道一个可以推另一个
- 常见柿子为:
\[f(n) = \sum\limits_{d|n}{g(d)} \iff g(n) = \sum\limits_{d|n}{\mu ({n \over d}) \times f(d)}
\]
- 我们发现这个东西长得像卷积,我们化一下,就有第二个形式:
\[f = I \ast g \iff g = \mu \ast f
\]
- 我们依据第二个形式给出证明
- 证明挺简单
证明
- 我们直接把左边带入,有
\[g = \mu \ast I \ast g
\]
- 由于结合律,有:
\[g = (\mu \ast I) \ast g
\]
- 我们上面提过一个性质:\(I \ast \mu = \epsilon\),所以有:
\[g = \epsilon \ast g
\]
- 就化为:
\[g = g
\]
- 证毕!
- 基础搞完了,讲道题
例题P2257 YY的GCD
- e,默认你会整除分块(数论分块)
- 我们直接转化题意,相当于求:
\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m} [\gcd(i,j) \in p]
\]
- 其中,\(p\) 代表素数
- 我们发现这个东西完全不可做,所以我们尝试直接枚举 \(p\),就有:
\[\sum\limits_{p}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m} [\gcd(i,j) = p]
\]
- 还是不好做,我们把 \(p\) 直接除掉,有:
\[\sum\limits_{p}\sum\limits_{i=1}^{\lfloor{n \over p}\rfloor}\sum\limits_{j=1}^{\lfloor{m \over p}\rfloor} [\gcd(i,j) = 1]
\]
- 我们发现后面的这个可以用莫反转化,就有:
\[ \sum\limits_{p}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}
\sum\limits_{d} [d|i] \times [d|j] \times \mu (d) \]
- 其中,\(d\) 是约数
- 我们发现这个 \(\sum\limits_{d}\) 有点碍事,可以直接交换枚举顺序,直接把这个东西提前,由于莫比乌斯函数仅与 \(d\) 有关,故也可以提前,有:
\[\sum\limits_{p}\sum\limits_{d}\mu (d)\sum\limits_{i=1}^{\lfloor{n \over p}\rfloor}\sum\limits_{j=1}^{\lfloor{m \over p}\rfloor}[d|i][d|j]
\]
- 我们考虑 \(\sum\limits_{i=1}^{\lfloor{n \over p}\rfloor}\sum\limits_{j=1}^{\lfloor{m \over p}\rfloor}[d|i][d|j]\) 的实际意义,我们发现就是分着求在 \(\lfloor {n \over p} \rfloor\) 中能整除 \(d\) 的个数,显然可以转化为 \(\lfloor{{\lfloor{n \over p}\rfloor} \over d}\rfloor\),可以举例算一下,\(m\) 同理,所以原式化为:
\[\sum\limits_{p}\sum\limits_{d}\mu (d) \lfloor{{\lfloor{n \over p}\rfloor} \over d}\rfloor \times \lfloor{{\lfloor{m \over p}\rfloor} \over d}\rfloor
\]
- 这个柿子很简了,但是我们还是不好做,先介绍一个定理方便化简:
\[\lfloor{{\lfloor{a \over b}\rfloor} \over c}\rfloor = \lfloor{a \over {b \times c}}\rfloor
\]
- 知道了这个,后面的柿子就化为:
\[\lfloor{n \over {p \times d}}\rfloor \times \lfloor{m \over {p \times d}}\rfloor
\]
- 就有原式:
\[\sum\limits_{p}\sum\limits_{d}\mu (d) \lfloor{n \over {p \times d}}\rfloor \times \lfloor{m \over {p \times d}}\rfloor
\]
- 我们令 \(T = p \times d\),就有:
\[\sum\limits_{T} \mu ({T \over p}) \lfloor{n \over T}\rfloor \times \lfloor{m \over T}\rfloor
\]
- 前面的柿子可以预处理出来,设一个数组为 \(k\),令 \(k_T = \sum\mu ({T \over k})\) 就行,后面的柿子可以用整除分块在 \(O(\sqrt n)\) 的复杂度内算出来
- 对了,后面的需要用高阶整除分块,这个怎么做呢,可以看看这篇的例题 \(5\),挺清晰msjing就不讲了,你非要看msjing也没法,在这是msjing的
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn=1e7+10;
int read()
{
int x=0,f=1;
char ch=getchar();
while (ch<'0' || ch>'9')
{
if (ch == '-') f=-1;
ch=getchar();
}
while (ch>='0' && ch<='9')
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x*f;
}
int n,m;
int prime[maxn],np[maxn];
int mo[maxn],k[maxn],s[maxn];
void getmo(int n)
{
// cerr << "---oh i am here---" << endl;
mo[1]=1;
for (int i=2;i<=n;i++)
{
if (!np[i])
prime[++prime[0]]=i,mo[i]=-1;
for (int j=1;j<=prime[0] && i*prime[j]<=n;j++)
{
np[i*prime[j]]=1;
if (!(i%prime[j]))
{
mo[i*prime[j]]=0;
break;
}
mo[i*prime[j]]=mo[i]*(-1);
}
}
// cerr << "---i can run here---" << endl;
for (int i=1;i<=prime[0];i++)
for (int j=1;j*prime[i]<=n;j++)
k[j*prime[i]]+=mo[j];
for (int i=1;i<=n;i++) s[i]=s[i-1]+k[i];
}
int get(int x,int y)
{
int res=0;
for (int i=1,j=0;i<=x;i=j+1)
j=min(x/(x/i),y/(y/i)),res+=(x/i)*(y/i)*(s[j]-s[i-1]);
return res;
}
signed main()
{
// cerr << "--------------" << endl;
getmo(maxn-10);
// cerr << "--------------" << endl;
int T=read();
while (T--)
{
n=read(),m=read();
if (n>m) swap(n,m);
// cerr << "-------------------" << endl;
printf("%lld\n",get(n,m));
// cerr << "---------------------" << endl;
}
return 0;
}
后记
- msjing就学到这了,更难的以后再说
- 谢谢ybc喵

浙公网安备 33010602011771号