本文中,约定 n≤m,a⊥b 表示 a 与 b 互质,P 为全体质数集合。
I
先来看一些函数:
φ(n)=|{x|x≤n,x⊥n}|(欧拉函数)
μ(n)=⎧⎪
⎪⎨⎪
⎪⎩0∃x≠1,x2|n1(∑[d|n,d∈P])mod2=0−1(∑[d|n,d∈P])mod2=1(莫比乌斯函数)
σ(n)=∑d|nd(除数函数)
上面这些函数都是数论函数,且为积性函数,即当 a⊥b 时满足 f(ab)=f(a)f(b)。
还有一些特殊的函数:
I(n)=1 (常函数)
id(n)=n (标号函数)
ε(n)=[n=1] (元函数)
这些函数在任何情况下都满足 f(ab)=f(a)f(b),被称为完全积性函数。
对于多项式函数,我们有一般的卷积;对于数论函数,我们有狄利克雷卷积:
f∗g=∑d|nf(d)g(nd)
那么有:
f∗ε=f
μ∗I=ε
φ∗I=id
μ∗id=φ
显然,狄利克雷卷积拥有交换律,结合律和分配律。
II
莫比乌斯反演公式:
f(n)=∑d|ng(d)→g(n)=∑d|nμ(d)f(nd)
证明:左等式告诉我们 f=g∗I,
所以右等式的右边 μ∗f=μ∗g∗I=g∗ε,也就等于 g。■
接下来证明一些做题时要用到的东西。
- ∑d|nμ(d)=[n=1]
证明:μ∗I=ε。■
- n∑i=1∑d|iμ(d)=n∑d=1⌊nd⌋μ(d)
证明:交换求和顺序即可,d 是 ⌊nd⌋ 个数的因子。■
注:对于上面这个式子,@qzz33554432提出了是否可以通过上一个引理推出它恒等于 1。实际上,在 d 没有取值限制时上式确实等于 1,但是当 d 有取值限制时它并不等于 1,但等号仍然成立。你将在下一个引理证明过程中明白我的意思。十分感谢!
- n∑i=1m∑j=1[i⊥j]=n∑d=1⌊nd⌋⌊md⌋μ(d)
证明:
n∑i=1m∑j=1[i⊥j]=n∑i=1m∑j=1[gcd(i,j)=1]=n∑i=1m∑j=1∑d|gcd(i,j)μ(d)=n∑i=1m∑j=1∑d|i∑d|jμ(d)=n∑i=1∑d|im∑j=1∑d|jμ(d)=n∑i=1∑d|im∑d=1⌊md⌋μ(d)=n∑d=1⌊nd⌋m∑d=1⌊md⌋μ(d)=n∑d=1⌊nd⌋⌊md⌋μ(d)■
III
- 求 n∑i=1m∑j=1[gcd(i,j)=k]。
n∑i=1m∑j=1[gcd(i,j)=k]=⌊nk⌋∑i=1⌊mk⌋∑j=1[gcd(i,j)=1]
就和上面一样了。
- 求 n∑i=1m∑j=1ij[gcd(i,j)=k]。
n∑i=1m∑j=1ij[gcd(i,j)=k]=⌊nk⌋∑i=1⌊mk⌋∑j=1ik×jk[gcd(i,j)=1]=k2⌊nk⌋∑i=1⌊mk⌋∑j=1ij∑d|i∑d|jμ(d)=k2⌊nk⌋∑d=1⌊nkd⌋∑i=1⌊mkd⌋∑j=1id×jdμ(d)=k2⌊nk⌋∑d=1d2μ(d)⌊nkd⌋∑i=1i⌊mkd⌋∑j=1j
这里后面的两个 Σ 是等差数列求和,可以 O(1) 计算,前面的可以整除分块做到 O(√n)。
- 求 n∑i=1m∑j=1lcm(i,j)。
n∑i=1m∑j=1lcm(i,j)=n∑i=1m∑j=1ijgcd(i,j)=n∑k=1n∑i=1m∑j=1ijk[gcd(i,j)=k]=n∑k=1⌊nk⌋∑i=1⌊mk⌋∑j=1ijk[gcd(i,j)=1]=n∑k=1⌊nk⌋∑i=1⌊mk⌋∑j=1ijk∑d|i∑d|jμ(d)=n∑k=1k⌊nk⌋∑d=1μ(d)d2⌊nkd⌋∑i=1i⌊mkd⌋∑j=1j
⌊nk⌋ 分块一次,⌊nkd⌋ 分块一次,总复杂度 O(√n)×O(√n)=O(n)。
接下来看一些例题吧。
IV
P1829
这题其实就是刚刚的那道 lcm。这里再讨论一种 O(n)−O(√n) 解法。
回到第三步:
n∑k=1⌊nk⌋∑i=1⌊mk⌋∑j=1ijk[gcd(i,j)=1]=n∑k=1k⌊nk⌋∑i=1⌊mk⌋∑j=1ij∑d|i∑d|jμ(d)=n∑k=1k⌊nk⌋∑d=1μ(d)d2⌊nkd⌋∑i=1i⌊mkd⌋∑j=1j
令 s=kd,则
n∑k=1⌊nk⌋∑i=1⌊mk⌋∑j=1ijk[gcd(i,j)=1]=n∑k=1k⌊nk⌋∑d=1μ(d)d2⌊ns⌋∑i=1i⌊ms⌋∑j=1j=n∑s=1s∑d|sμ(d)d⌊ns⌋∑i=1i⌊ms⌋∑j=1j
现在的 ∑d|sμ(d)d 可以 O(n) 线性筛出,剩下的东西做一次分块可以 O(√n)。
P2257
求 n∑i=1m∑j=1[gcd(i,j)∈P]。
n∑i=1m∑j=1[gcd(i,j)∈P]=k∈[1,n]∩P∑k⌊nk⌋∑i=1⌊mk⌋∑j=1[gcd(i,j)=1]=k∈[1,n]∩P∑kn∑d=1⌊nkd⌋⌊mkd⌋μ(d)
令 s=kd,则
n∑i=1m∑j=1[gcd(i,j)∈P]=k∈[1,n]∩P∑kn∑d=1⌊ns⌋⌊ms⌋μ(d)=n∑s=1⌊ns⌋⌊ms⌋k∈P∑k|sμ(sk)
右边的 Σ 可以筛完预处理,左边的分块即可。
P3312
求 n∑i=1m∑j=1σ(gcd(i,j))[σ(gcd(i,j))≤a]。
n∑i=1m∑j=1σ(gcd(i,j))=n∑d=1σ(d)n∑i=1m∑j=1[gcd(i,j)=d]=n∑d=1σ(d)⌊nd⌋∑i=1⌊md⌋∑j=1[gcd(i,j)=1]=n∑d=1σ(d)⌊nd⌋∑k=1⌊nkd⌋⌊mkd⌋μ(d)
令 s=kd,则
n∑i=1m∑j=1σ(gcd(i,j))=n∑d=1σ(d)⌊nd⌋∑k=1⌊ns⌋⌊ms⌋μ(k)=n∑s=1∑d|sσ(d)μ(sd)⌊ns⌋⌊ms⌋=n∑s=1⌊ns⌋⌊ms⌋∑d|sσ(d)μ(sd)
这个式子已经足够漂亮了。
接下来考虑将每个询问按 a 排序,对于每次新加进满足域的 σ(d),我们枚举 s≤n 使得 d|s,这个 s 为答案加上 σ(d)μ(sd) 的贡献。
注意到分块的时候需要用到区间求和,所以现在需要一个支持”单点加贡献,区间查询“的东西。这个用树状数组维护即可。
复杂度 O(nlog2n+T√nlogn)。
P4318
求第 k 个不含完全平方因子的数。
首先二分答案,接下来要解决的就是 1∼mid 中有多少个不含完全平方因子的数。
容斥一下,我们筛去 22 的倍数,筛去 32 的倍数。注意到 4 有完全平方因子,肯定之前已经被筛过了,所以可以直接跳过。
继续筛去 52 的倍数,然后发现 62 被 22 和 32 筛了两遍,所以应该加回来一遍。
于是,我们现在需要这个一个函数:
-
对于含完全平方因子的数,返回值为 0。
-
对于质因子个数为奇数的数,返回值为 −1。
-
对于质因子个数为偶数的数,返回值为 1。
显然这个函数就是 μ。
最后答案为 √n∑i=1μ(i)⌊ni2⌋,O(√n) 暴力计算即可。
P6271
给你 n=w∏i=1pαii,求 n∑i=1id[gcd(i,n)=1]。
n∑i=1id[gcd(i,n)=1]=n∑i=1id∑k|i∑k|nμ(k)=∑k|nμ(k)nk∑i=1(ik)d=∑k|nμ(k)kdnk∑i=1id
设 f(x)=x∑i=1id,我们知道这个函数一定可以表示成一个关于 x 的 d+1 次多项式,而且我们可以在 O(d3) 或者 O(d2) 的时间内用插值,消元或者伯努利公式求出它的系数。
于是设 f(x)=d+1∑i=0aixi,则
n∑i=1id[gcd(i,n)=1]=∑k|nμ(k)kdf(nk)=∑k|nμ(k)kdd+1∑i=0ai(nk)i=d+1∑i=0aini∑k|nμ(k)kd−i
设 g(n)=∑k|nμ(k)kd−i,这个函数显然是积性函数,于是有
g(n)=w∏j=1g(pαjj)
观察 g(pα),发现 k 只能等于 1,p,p2,p3⋯
而且仅当 k=1 或 p 时 μ 不为 0。所以
g(n)=w∏j=1μ(1)+μ(pj)pd−ij=w∏j=11−pd−ij
带回去可以得到原式 =d+1∑i=0ainiw∏j=11−pd−ij,这个式子已经可以 O(dw) 计算。
最终复杂度为 O(d3+dw) 或 O(d2+dw)。
BZOJ3309
n∑i=1m∑j=1f(gcd(i,j))=n∑d=1f(d)n∑i=1m∑j=1[gcd(i,j)=d]=n∑d=1f(d)⌊nd⌋∑i=1⌊md⌋∑j=1[gcd(i,j)=1]=n∑d=1f(d)⌊nd⌋∑k=1⌊nkd⌋⌊mkd⌋μ(k)
设 s=kd,则
n∑i=1m∑j=1f(gcd(i,j))=n∑d=1f(d)⌊nd⌋∑k=1⌊ns⌋⌊ms⌋μ(k)=n∑s=1⌊ns⌋⌊ms⌋∑d|sf(d)μ(sd)
左边已经可以分块,观察右边的 Σ:
考虑设 s=w∏i=1pkii,由于式子里有个 μ(sd),因此若设 d=w∏i=1paii,仅当 ki−ai=0 或 1 时式子才有贡献。
分类讨论:
-
当存在 (i,j) 满足 ki<kj 时,ai 的取值显然不会影响到 f 函数的值,但会影响到 μ 函数的值,这两个值正好相反。于是就全部抵消掉了,式子值为 0。
-
当所有 ki 都相等时,设 t=max{ki},则 f(d)=t 对答案的贡献为
∑f(sd)=tf(d)μ(sd)=t∑f(d)=tμ(sd)=tw∑i=1(−1)w−i(wi)=t(1−1)w−t(−1)w=t(−1)w+1
当 f(d)=t−1 时,所有 ai 都等于 ki−1,所以它对答案的贡献为 (t−1)×(−1)w。
综合起来,所有 ki 都相等时式子值为 t(−1)w+1+(t−1)×(−1)w=(−1)w+1。
接下来随便筛一下就可以 O(n+T√n) 了。
P3704
求 n∏i=1m∏j=1fgcd(i,j),f 是斐波那契数列。
n∏i=1m∏j=1fgcd(i,j)=n∏d=1f∑ni=1∑mj=1[gcd(i,j)=d]d=n∏d=1f∑⌊nd⌋i=1∑⌊md⌋j=1[gcd(i,j)=1]d=n∏d=1f∑⌊nd⌋k=1⌊nkd⌋⌊mkd⌋μ(k)d
令 s=kd,则
n∏i=1m∏j=1fgcd(i,j)=n∏d=1f∑⌊nd⌋k=1⌊ns⌋⌊ms⌋μ(k)d=n∏s=1∏d|sf⌊ns⌋⌊ms⌋μ(sd)d=n∏s=1(∏d|sfμ(sd)d)⌊ns⌋⌊ms⌋
这里你发现括号里的东西与 n,m 无关,并且可以 O(nlogn+nlogmod) 预处理出来,外面的部分则可以分块。最后算上快速幂,复杂度 O(nlogn+T√nlogmod)。
P5518
求 A∏i=1B∏j=1C∏k=1(lcm(i,j)gcd(i,k))f(type),其中 type∈{0,1,2},f(type) 分别等于 1,ijk,gcd(i,j,k)。
首先 A∏i=1B∏j=1C∏k=1(lcm(i,j)gcd(i,k))f(type)=A∏i=1B∏j=1C∏k=1(ijgcd(i,j)gcd(i,k))f(type)
我们把分子分母分开来算,现在要做的就是计算 A∏i=1B∏j=1C∏k=1if(type) 和 A∏i=1B∏j=1C∏k=1gcd(i,j)f(type)。
接下来分 type 考虑吧。
type=0,f(type)=1
A∏i=1B∏j=1C∏k=1i=A∏i=1iBC=(A!)BC
A∏i=1B∏j=1C∏k=1gcd(i,j)=A∏i=1B∏j=1gcd(i,j)C
你会发现 A∏i=1B∏j=1gcd(i,j) 这个式子和我们上一题研究的式子基本上是一样的,它等于
A∏s=1(∏d|sdμ(sd))⌊As⌋⌊Bs⌋
记住这个式子,它在我们下面的推导中还会用到。
这样我们在 O(√nlogn) 的时间内解决了 type=0 的情况。
type=1,f(type)=ijk
设 Σ(n)=n∑i=1i=n(n+1)2
A∏i=1B∏j=1C∏k=1iijk=(A∏i=1ii)Σ(B)Σ(C)
A∏i=1B∏j=1C∏k=1gcd(i,j)ijk=(A∏i=1B∏j=1gcd(i,j)ij)Σ(C)=⎛⎜⎝A∏d=1⌊Ad⌋∏i=1⌊Bd⌋∏j=1did×jd[gcd(i,j)=1]⎞⎟⎠Σ(C)=⎛⎜⎝A∏d=1⌊Ad⌋∏i=1⌊Bd⌋∏j=1dijd2∑k|i∑k|jμ(k)⎞⎟⎠Σ(C)=⎛⎜⎝A∏d=1⌊Ad⌋∏k=1dμ(k)k2d2Σ(⌊Akd⌋)Σ(⌊Bkd⌋)⎞⎟⎠Σ(C)
令 s=kd,则
A∏i=1B∏j=1C∏k=1gcd(i,j)ijk=⎛⎜⎝A∏d=1⌊Ad⌋∏k=1dμ(k)s2Σ(⌊As⌋)Σ(⌊Bs⌋)⎞⎟⎠Σ(C)=⎛⎜
⎜⎝A∏s=1⎛⎝∏d|sdμ(sd)⎞⎠s2Σ(⌊As⌋)Σ(⌊Bs⌋)⎞⎟
⎟⎠Σ(C)
中间括号内的式子我们是预处理过的,这里再预处理它的 s2 次幂就好了。
分一次块,复杂度 O(√nlogn)。
type=2,f(type)=gcd(i,j,k)
阴间task
前置知识:欧拉反演
我们知道 n=∑d|nφ(d)
把 n 换掉,于是 gcd(i,j)=∑d|gcd(i,j)φ(d)=∑d|i∑d|jφ(d)
那么 n∑i=1gcd(i,x)=n∑i=1∑d|i∑d|xφ(d)=∑d|xn∑i=1∑d|iφ(d)=∑d|x⌊nd⌋φ(d)
上式被称为欧拉反演。
A∏i=1B∏j=1C∏k=1igcd(i,j,k)=A∏i=1i∑Bj=1∑Ck=1gcd(k,gcd(i,j))
最右边可以欧拉反演,于是
A∏i=1B∏j=1C∏k=1igcd(i,j,k)=A∏i=1i∑Bj=1∑d|i∑d|j⌊Cd⌋φ(d)=A∏i=1i∑d|i∑Bj=1∑d|j⌊Cd⌋φ(d)=A∏i=1i∑d|i⌊Bd⌋⌊Cd⌋φ(d)=A∏d=1⎛⎜⎝⌊Ad⌋∏i=1id⎞⎟⎠⌊Bd⌋⌊Cd⌋φ(d)=A∏d=1(d⌊Ad⌋⌊Ad⌋!)⌊Bd⌋⌊Cd⌋φ(d)
预处理 dφ(d) 前缀积再做一次分块即可 O(√nlogn)。
接下来设 G(n,x)=n∑i=1gcd(i,x)=∑d|x⌊nd⌋φ(d)。
A∏i=1B∏j=1C∏k=1gcd(i,j)gcd(i,j,k)=A∏i=1B∏j=1gcd(i,j)∑Ck=1gcd(gcd(i,j),k)=A∏i=1B∏j=1gcd(i,j)G(C,gcd(i,j))=A∏d=1dG(C,d)∑⌊Ad⌋i=1∑⌊Bd⌋j=1[gcd(i,j)=1]=A∏d=1d∑q|d⌊Cq⌋φ(q)∑⌊Ad⌋k=1⌊Akd⌋⌊Bkd⌋μ(k)=A∏q=1⌊Aq⌋∏d=1(dq)⌊Cq⌋φ(q)∑⌊Adq⌋k=1⌊Akdq⌋⌊Bkdq⌋μ(k)
考虑 d,q 分开计算。
令 s=kd,则
A∏q=1⌊Aq⌋∏d=1d⌊Cq⌋φ(q)∑⌊Adq⌋k=1⌊Akdq⌋⌊Bkdq⌋μ(k)=A∏q=1⌊Aq⌋∏d=1d⌊Cq⌋⌊Asq⌋⌊Bsq⌋φ(q)∑⌊Adq⌋k=1μ(k)=A∏q=1⎛⎜
⎜⎝⌊Aq⌋∏s=1⎛⎝∏d|sdμ(sd)⎞⎠⌊Asq⌋⌊Bsq⌋⎞⎟
⎟⎠φ(q)⌊Cq⌋
你惊奇地发现最外层括号里面的东西我们在 type=0 时研究过了。
这样外层一次分块,里层一次分块就完事了。
复杂度 √n∑i=1√nilogni=O(n34logn)。
还有 q,同样令 s=kd:
A∏q=1⌊Aq⌋∏d=1q⌊Cq⌋φ(q)∑⌊Adq⌋k=1⌊Akdq⌋⌊Bkdq⌋μ(k)=A∏q=1q⌊Cq⌋φ(q)∑⌊Aq⌋s=1⌊Asq⌋⌊Bsq⌋∑k|sμ(k)=A∏q=1q⌊Cq⌋φ(q)∑⌊Aq⌋s=1⌊Asq⌋⌊Bsq⌋[s=1]=A∏q=1q⌊Aq⌋⌊Bq⌋⌊Cq⌋φ(q)
一次分块即可,复杂度 O(√nlogn)。
V
感谢 cyffff 神仙对我的文章的支持。本文中的部分推导和例题来自他的文章。
感谢 An_account 大佬,他的文章是一篇很好的入门文章,引领了我踏入莫反的大门。
本文中的部分思路借鉴自题解区的文章。感谢这些文章的作者们。
本文可能随时作出修改,希望各位积极提出修改意见。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现