5 月做题记录
\(\text{2025/5/1}\)
AtCoder ABC402F Path to Integer
首先令 \(a_{i,j}\leftarrow a_{i,j}\times 10^{n-i+n-j}\),那么问题转化成网格上走路径,使得权值和 \(\bmod{m}\) 最大。爆搜复杂度为 \(\binom{2n-1}{n-1}\),无法承受。考虑折半搜索,我们从起点开始搜出走 \(n-1\) 步的所有状态 \(S_1\),终点也做一遍,得到状态 \(S_2\),状态集合内按最终的 \(x\) 坐标分组。枚举 \(x\),对 \(S_{2,x}\) 按路径权值和排序,遍历 \(S_{1,x}\) 中的每个权值 \(i\),在 \(S_{2,x}\) 中二分出最大的 \(j\) 使得 \(i+j<m\Leftrightarrow j<m-i\),若不存在这样的 \(j\) 就取最大值,更新答案即可。时间复杂度 \(\mathcal{O}(n2^n)\)。
Luogu P2391 白雪皑皑
注意到一个点的颜色由最后一次染色决定,于是我们倒序染色,并查集维护序列连通性。具体来说,令 \(fa_i\) 表示 \([i,n]\) 中最靠左的未染色的点,染色时暴力跳即可。时间复杂度 \(\mathcal{O}(n\log{n}+m)\)。
Luogu P12391 「RiOI-6」帝国少女
先做比较好做的 \(m>2\) 的情况。考虑此时一个序列的权值如何计算,我们按照极长同色段进行划段,对每个段计算最小修改次数。容易发现长度为 \(len\) 的段的最小修改次数就是 \(\left\lfloor\frac{len}{2}\right\rfloor\)。
那么我们就是要快速计算所有子区间的 \(\sum\left\lfloor\frac{len}{2}\right\rfloor\) 之和。我们类似扫描线去扫右端点 \(r\),当 \(r\leftarrow r+1\) 时,维护所有以 \(r\) 为右端点的区间的贡献和 \(s\)。这个不难算,考虑 \(r\) 所在的极长段 \([pre_r,r]\),分类讨论 \(1\leq l<pre_r\) 和 \(pre_r\leq l\leq r\) 的情况即可。这部分是 \(\mathcal{O}(n)\) 的。
再来做 \(m=2\)。这时候我们换种思路,注意到只会把序列改成 \(0,1,0,\cdots\) 或者 \(1,0,1,\cdots\),那么一个序列的权值自然就是两种修改方式的操作次数取最小值。容易看出两种修改方式操作次数之和就是序列的长度。我们预处理 \(pre_i\) 表示将 \(a[1,i]\) 修改成 \(0,1,0,\cdots\) 的最小操作次数,那么我们要求的就是
看起来不好优化,考虑拆 \(\min\),也就是考虑
我们略去 \(\frac{1}{2}\),于是原式变为
令 \(b_i=i-2pre_i\),则原式即
后面的求和相当于 \(b_0,\cdots,b_n\) 中两两的差的绝对值之和,这就很典了。我们对 \(b\) 排序,然后用前缀和累加答案即可。
拼接两部分做法即可通过本题。时间复杂度 \(\mathcal{O}(n\log{n})\),瓶颈在于排序。
Codeforces 995F Cowmpany Cowmpensation
容易得到 \(\mathcal{O}(nV)\) 的 树形 DP,令 \(f_{u,i}\) 表示考虑 \(sub_u\),点 \(u\) 填 \(i\) 的方案数,于是
后缀和优化即可。
考虑绕开值域的限制。不妨构造多项式 \(F_u(x)\) 使得 \(F_u(i)=f_{u,i}\),那转移相当于对儿子的多项式做前缀和变换再乘起来。显然叶子节点处的多项式是一个常数,于是容易证明 \(F_u(x)\) 是一个 \(sz_u-1\) 次多项式。那么我们只需要对每个点维护其多项式在 \([1,n]\) 处的点值,暴力转移即可,最后对 \(F_1(x)\) 做前缀和变换,然后用拉格朗日插值计算 \(F_1'(V)\) 即可。时间复杂度 \(\mathcal{O}(n^2)\)。
\(\text{2025/5/2}\)
Luogu P12397 「FAOI-R9」函数大师
先特判掉 \(k=0\) 的情况。显然 \(s(x)\) 会在不超过 \(3\) 迭代后收敛成 \((x-1)\bmod{9}+1\),于是容易 \(\mathcal{O}(\log{x})\) 计算 \(f_k(x)\)。注意到 \(S_1(x)\leq 9\times 18\),我们提前对于每个 \(1\leq x\leq 9\times 18\) 的 \(x\) 计算出 \(\sum_{i=0}^{k-1}S_i(x)\),询问时暴力枚举 \(x\) 匹配即可。令 \(B=9\times 18\),时间复杂度为 \(\mathcal{O}(B\log{B}+TB\log{m})\)。
\(\text{2025/5/3}\)
Luogu T605222 250503T3
题意:一个环上面排列着 \(n\) 个点,编号为 \(0,1,\cdots,n-1\)。现在可以花费 \(c_i\) 的代价连接 \(i\) 和 \(i+1\)。给出 \(p\) 条限制 \((a_i,b_i)\),表示要求 \(a_i\) 和 \(b_i\) 连通。求满足所有限制花费的最小代价。
枚举断边,这样限制就被定向了,差分计算总代价,这样就得到了 \(\mathcal{O}(np)\) 做法。考虑优化,注意到断边由 \((i-1,i)\) 变为 \((i,i+1)\) 的过程中变化的区间不多,把变化的区间处理出来,对它们做区间 \(\pm1\) 即可。这样转化成支持区间 \(\pm1\),求值 \(>0\) 的对应位置的权值和。由于每个位置的值必然是非负的,于是直接上线段树,标记永久化即可维护。时间复杂度 \(\mathcal{O}(n\log{n}+p)\)。
\(\text{2025/5/4}\)
Luogu P2398 GCD SUM
整除分块即可,时间复杂度 \(\mathcal{O}(n)\)。
Luogu P1390 公约数的和
双倍经验 Luogu P2398,减掉 \(\frac{n(n+1)}{2}\) 再除以 \(2\) 即可。
Luogu P12392 「RiOI-6」Re:帝国少女
很好的细节 DP 题,使我大脑飞速旋转。
先做 \(m=2\) 的情况。若 \(2k\neq n\),则只能修改为 \(0,1,\cdots\) 和 \(1,0,\cdots\) 中的一种,各从中选择 \(k\) 位翻转就是对应的原序列,方案数为 \(2\binom{n}{k}\);若 \(2k=n\),有 \(2\) 种修改方案,方案数为 \(\binom{n}{k}\),答案为 \(2\binom{n}{k}\)。因此,对于 \(m=2\) 的情况,输出 \(2\binom{n}{k}\) 即可。
再做 \(m>2\) 的情况。还是按极长同色段划分序列,我们先不考虑颜色,思考一个段内的修改方案是怎么样的(我们用 \(0/1\) 表示对应位置是否修改):
- 若长度为奇数,显然只有 \(010\cdots 010\) 这种修改方案。
- 若长度为偶数:比较显然有 \(0101\cdots 01\) 和 \(1010\cdots 10\) 这 \(2\) 种方案,还有一种容易忽略的方案是 \(0101\cdots11\cdots1010\),也就是修改中间的连续 \(2\) 个位置 \((i,i+1)\),其中 \(i\) 是偶数。计算可得我们能选出 \(\frac{len}{2}-1\) 个这样的 \(i\)。
考虑颜色的限制,我们发现当前段的染色方案数。只会受前面段原来的颜色和前面段最后一个位置的颜色限制,由此设计 DP 状态:令 \(f_{i,j,0/1}\) 表示考虑 \(a[1,i]\),所有满足 \(f(a[1,i])=j\) 的 \(g(a[1,i])\) 之和。转移时我们枚举 \(k\) 表示 \(i\) 所在颜色段的长度,根据 \(k\) 的奇偶性分类讨论,需要特判 \(j=\left\lfloor\frac{i}{2}\right\rfloor\) 的情况。
下文中我们令 \(t=\left\lfloor\frac{k}{2}\right\rfloor\)。
\(f\) 的计算包含两部分:当前段的初始方案数和染色方案数。
对于当前段的初始方案数,讨论 \(f_{i-k,j-t,0/1}\) 中 \(0/1\) 的取值:
- 若取值为 \(0\),则当前段的颜色与前面的段的颜色不同即可,有 \(m-1\) 种。
- 若取值为 \(1\),则当前段的颜色既需要与前面的段不同,也需要和前面的段的最后一个位置修改后的颜色不同,有 \(m-2\) 种。这是大部分情况,但是有一个 corner case:若我们在当前段修改了首位的颜色,则段的初始颜色不必与最后一个位置修改后的颜色不同,此时有 \(m-1\) 种方案。
对于染色方案数,分别考虑首位和其他位的染色方案数即可,如果是连续修改中间的 \(2\) 位也需要考虑进去。读者可以自行推导。
这样我们就得到了 \(\mathcal{O}(n^3)\) 的朴素 DP。
考虑优化。我们发现转移式中大部分都是乘上 \(m-1\) 或者 \(m-2\) 的形式,可以提出来,于是需要快速计算包含 \(k\) 和 \(t\) 的那部分式子,更具体地,我们要维护出
以及
容易想到前缀和优化。我们分奇偶维护,令
不难列出转移方程:
容易用 \(g\) 和 \(h\) 对应计算出我们所需的式子做到 \(\mathcal{O}(1)\) 转移。时间复杂度 \(\mathcal{O}(n^2)\)。
UVA 11417 GCD
双倍经验 Luogu P1390。
UVA 11424 GCD - Extreme (I)
三倍经验 Luogu P1390。
UVA 11426 GCD - Extreme (II)
四倍经验 Luogu P1390。
SPOJ 3871 GCDEX - GCD Extreme
五倍经验 Luogu P1390。
Codeforces 1561D1 Up the Strip (simplified version)
考虑 DP。令 \(f_i\) 表示从 \(i\) 变成 \(1\) 的方案数。转移方程就是:
前缀和+整除分块优化即可。时间复杂度 \(\mathcal{O}(n\sqrt{n})\)。
Codeforces 1561D2 Up the Strip
换一种思路,转而考虑 \(f_i\) 会转移到哪些位置。首先可以转移到 \(f[i+1,n]\) 这个后缀,其次考虑枚举 \(j\),那么 \(f_i\) 也会转移到 \(f[ij,(i+1)j-1]\) 上。我们发现这就是调和级数,区间加可以直接差分。时间复杂度 \(\mathcal{O}(n\log{n})\)。
Codeforces 1558E Up the Strip
双倍经验 Codeforces 1561D2。
Luogu P5091 【模板】扩展欧拉定理
扩展欧拉定理:
算出 \(\varphi(m)\) 后,边读入 \(b\) 边模即可。计算 \(a^b\bmod{m}\) 的时间复杂度为 \(\mathcal{O}(\log(\min(b,\varphi(m))))\)。
Luogu P4139 上帝与集合的正确用法
根据扩展欧拉定理,我们有
线性筛出 \(\varphi\),对上面的式子递归计算即可,边界为 \(p=1\)。注意到 \(\varphi(x)\bmod{2}=0(x>1)\),且 \(\varphi(2x)\leq x\),因此至多递归 \(\mathcal{O}(\log{p})\) 次,由主定理,时间复杂度为 \(\mathcal{O}(p+T\log^2p)\)。
Luogu P3911 最小公倍数之和
令 \(c_i\) 表示 \(a\) 中 \(i\) 的出现次数,那么原式即为
把 \(\operatorname{lcm}(i,j)\) 替换成 \(\frac{ij}{\gcd(i,j)}\),然后莫反:
套路地枚举 \(T=dt\),原式变为
\(\sum_{d\mid T}\mu(d)d\) 可以直接调和级数 \(\mathcal{O}(V\log{V})\) 预处理,\(\sum_{i=1}^{\frac{V}{T}}c_{iT}i\) 也可以暴力计算,依然是 \(\mathcal{O}(V\log{V})\) 的。时间复杂度 \(\mathcal{O}(V\log{V})\)。
AtCoder AGC038C LCMs
双倍经验 Luogu P3911,减掉 \(\sum_{i=1}^na_i\) 再除以 \(2\) 就是答案。
Luogu P3327 [SDOI2015] 约数个数和
我们先指出
证明:
设 \(x\) 的质因子集合为 \(X\),\(y\) 的质因子集合为 \(Y\),\(\gcd(x,y)\) 的质因子集合为 \(S\)。定义 \(c_x(p),c_y(p)\) 分别表示 \(p\) 在 \(x,y\) 中的指数。枚举 \(x\) 的约数等价于从 \(X\backslash S,S\) 中各选出一个子集拼在一起,然后给质因子标上限制范围内的指数,\(y\) 同理。
容易发现 \(X\backslash S,Y\backslash S\) 的子集怎么选都是互质的,这样子就乘上了 \(\prod_{p\in X\backslash S}(c_x(p)+1)\times\prod_{p\in Y\backslash S}(c_y(p)+1)\) 的贡献。
再来看从 \(S\) 中选出的两个子集。分别考虑每个质因子 \(p\),我们可以不选,可以选 \(p^k(1\leq k\leq c_x(p))\) 当成 \(x\) 的因子,也可以选 \(p^k(1\leq k\leq c_y(p))\) 当成 \(y\) 的因子,因此每个质因子都会乘上 \(c_x(p)+c_y(p)+1\) 的贡献。于是总贡献就是
\[\prod_{p\in X\cup Y}(c_x(p)+c_y(p)+1) \]这显然等于 \(d(xy)\)。\(\Box\)
套上这个式子,莫反:
令 \(f(n)=\sum_{i=1}^n\left\lfloor\frac{n}{i}\right\rfloor\),那么上式变为
视 \(n,m\) 同阶,容易 \(\mathcal{O}(n\sqrt{n})\) 预处理出 \(f\),整除分块即可。时间复杂度 \(\mathcal{O}((n+T)\sqrt{n})\)。
\(\text{2025/5/5}\)
Luogu T605873 最大公约数(gcd)
题意:给定一个长度为 \(n\) 的环形序列 \(a\),现将其划分为 \(k\) 段,定义一种划分方案的权值为各段和的 \(\gcd\)。对于每个 \(1\leq k\leq n\),求划分的最大权值。\(1\leq n\leq 2\times 10^3\),\(1\leq a_i\leq 5\times 10^7\)。
设 \(s=\sum_{i=1}^na_i\),注意到每种划分方案的权值必然是 \(s\) 的约数。同时,我们观察到,如果存在一种权值为 \(d\) 划分为 \(k\) 段的划分方案,我们合并相邻的段就变成了划分为 \(i(1\leq i<k)\) 段的方案。因此如果固定划分权值 \(d\),我们只需要计算它最多可以划分成多少段。
于是枚举 \(d\mid s\),考虑计算最多划分成多少段。考虑前缀和数组 \(pre\),对于一个段 \([l,r]\),它需要满足 \(d\mid (pre_r-pre_{l-1})\Leftrightarrow pre_{l-1}\equiv pre_r\pmod{d}\),因此划分点处的 \(pre\) 值 \(\bmod{d}\) 相等。特别考虑前后缀,我们发现由于是环形序列它们恰好拼成一个合法的段。开 map 取最大值即可 \(\mathcal{O}(n\log{d})\) 算出答案。每次枚举 \(d\) 计算出的答案会对一个前缀造成贡献,做一个后缀最大值就可以得到最终答案。时间复杂度 \(\mathcal{O}(\sqrt{nV}n\log{(nV)})\)。
Luogu T605876 最低位(lowbit)
题意:对于一个数 \(x\),定义对 \(x\) 的一次变换为:有 \(50\%\) 的概率变为 \(x+\operatorname{lowbit}(x)\),\(50\%\) 的概率变为 \(x-\operatorname{lowbit}(x)\)。令 \(f(x)\) 表示将 \(x\) 变换为 \(0\) 的期望变换次数。给定 \(l,r\),求 \(\sum_{i=l}^rf(i)\),答案对 \(998244353\) 取模。\(1\leq l\leq r<2^{31}\)。
根据定义容易得出递推式:
注意到若 \(x\neq 2^k(k\in\mathbb{N})\), 则 \(x\) 变换后 \(\operatorname{lowbit}\) 单调递增,于是考虑计算 \(f(2^k)\),显然此时我们有:
令 \(g(2^k)=f(2^k)-2\),那么上式等价于 \(g(2^{k+1})=2g(2^k)\)。由于期望需要收敛,因此必有 \(g(2^k)=0\),于是 \(f(2^k)=2\)。
回过头考虑普通的 \(x\),由于 \(\operatorname{lowbit}\) 单调递增,因此如果我们对其进行记忆化搜索,至多 \(\log{V}\) 次递归后 \(x\) 就会变成 \(2^k\)。那么开一个 map,我们就可以 \(\log^2{V}\) 计算一个单点的 \(f(x)\)。
题目要求计算区间和,差分成前缀和 \(\sum_{i=1}^nf(i)\)。考虑所有 \(\leq n\) 的奇数 \(2k+1\),我们有
因此我们可以递归成所有偶数 \(i\) 的 \(f\) 值之和。再考虑所有 \(\leq n\) 的偶数 \(2k\),注意到 \(\operatorname{lowbit}(2k)=2\operatorname{lowbit}(k)\),于是
根据上式,容易从 \(f(2^k)=f(2^{k+1})\) 推广成 \(f(k)=f(2k)\),于是我们可以把偶数位置的和变成奇数位置的和,继续递归下去。时间复杂度 \(\mathcal{O}(\log^2{V})\)。
\(\text{2025/5/6}\)
Luogu P4449 于神之怒加强版
枚举 \(\gcd\),莫反:
令 \(f=\operatorname{id}^k*\ \mu\),考虑线性筛出 \(f(n)\)。分类讨论:
- \(n=p\):\(f(p)=p^k-1\)。
- \(n=ip(p\not\mid i)\):\(f(ip)=f(i)f(p)=f(i)(p^k-1)\)。
- \(n=ip(p\mid i)\):考虑利用 \(f\) 的积性对其展开。易得 \(f(p^c)=p^{ck}-p^{(c-1)k}\),因此若 \(n=\prod_{i=1}^kp_i^{c_i}\),则 \(f(n)=\prod_{i=1}^k(p_i^{c_ik}-p_i^{(c_i-1)k})\)。于是当 \(n\leftarrow np\) 时,\(f(n)\leftarrow p^kf(n)\),因此 \(f(n)=f(i)p^k\)。
同时线性筛出 \(\operatorname{id}^k\) 即可。时间复杂度 \(\mathcal{O}(n+T\sqrt{n})\)。
Luogu P4213 【模板】杜教筛
对于计算数论函数 \(f(n)\) 的前缀和函数 \(S(n)\),核心思想就是构造出 \(S(n)\) 关于 \(S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)\) 的递推式。杜教筛则考虑另一个数论函数 \(g\)。观察它们的狄利克雷卷积的前缀和:
于是
因此,杜教筛要求我们找到构造一个合适的数论函数 \(g\),使得我们可以快速计算 \(f*g\) 的前缀和以及 \(g\) 的前缀和。
考虑对 \(S(n)\) 用 map/unordered_map 记忆化,如果表中没有存储 \(S(n)\) 就整除分块暴力计算。可以证明这样做杜教筛时间复杂度是 \(\mathcal{O}(n^{\frac{3}{4}})\) 的。但我们可以继续优化,设一个阈值 \(B\geq\sqrt{n}\),我们预处理所有 \(1\leq n\leq B\) 的 \(S(n)\)。设预处理复杂度为 \(T(B)\),可以证明这样做杜教筛时间复杂度是 \(\mathcal{O}(T(B)+\frac{n}{\sqrt{B}})\) 的。通常我们做线性筛预处理,也就是 \(T(B)=\mathcal{O}(B)\),此时取 \(B=n^{\frac{2}{3}}\) 时间复杂度最优,为 \(\mathcal{O}(n^{\frac{2}{3}})\)。
模板题要求 \(\varphi\) 和 \(\mu\) 的前缀和,构造 \(g=1\) 即可。时间复杂度 \(\mathcal{O}(n^{\frac{2}{3}})\)。
Luogu P3768 简单的数学题
枚举 \(\gcd\),莫反:
其中 \(f(n)=\sum_{i=1}^ni=\frac{n(n+1)}{2}\)。令 \(g=\operatorname{id}^2\varphi\),考虑用杜教筛计算其前缀和。遇到 \(\operatorname{id}^k\) 考虑套路地卷上一个 \(\operatorname{id}^k\),对本题而言,计算可得 \((\operatorname{id}^2\varphi)*\operatorname{id}^2=\operatorname{id}^2(\varphi*1)=\operatorname{id}^3\)。因此我们卷上 \(\operatorname{id}^2\) 就可以对 \(g\) 做杜教筛了。需要快速计算 \(\operatorname{id}^3\) 的前缀和 \(S'(n)\),这个其实就是 \(S'(n)=\frac{n^2(n+1)^2}{4}\)。时间复杂度 \(\mathcal{O}(n^{\frac{2}{3}})\)。
\(\text{2025/5/8}\)
Luogu P5221 Product
化 \(\operatorname{lcm}(i,j)\) 为 \(\frac{ij}{\gcd(i,j)}\),得到:
式子拆成分子分母两部分。对于分子,
对于分母,枚举 \(\gcd\),化成欧拉函数前缀和的形式:
其中 \(s_n=\sum_{i=1}^n\varphi(i)\)。预处理 \(s\) 时在模 \(MOD-1\) 意义下进行,然后快速幂暴力计算即可。时间复杂度 \(\mathcal{O}(n\log{n})\)。
SPOJ 26017 GCDMAT - GCD OF MATRIX
二维差分成前缀的形式,然后欧拉反演:
然后整除分块即可。时间复杂度 \(\mathcal{O}(n+T\sqrt{n})\)。
SPOJ 26045 GCDMAT2 - GCD OF MATRIX (hard)
毒瘤卡常题。在 SPOJ 26017 的基础上加上一些常数优化:
- 预处理出 \(inv_i=\frac{1}{i}\),用乘法代替除法,需要乘上 \(1+10^{-15}\) 规避精度问题。
- 根号分治。设阈值 \(B\),\(\leq B\) 的部分暴力累加,\(>B\) 的部分整除分块计算。本题大概取 \(B=\lfloor\sqrt{7\min(n,m)}\rfloor\) 效率较高。
Luogu P5176 公约数
评黑显然高了。
我们首先指出:
证明:
单独考虑每个质因子的指数,发现上式等价于证明
\[\min(a+b,a+c,b+c)=\min(a,b)+\min(a,c)+\min(b,c)-\min(a,b,c) \]钦定 \(a\leq b\leq c\),那么左边即 \(a+b\),右边即 \(a+a+b-a=a+b\)。\(\Box\)
那么原式变为
问题转化为快速计算 \(\sum_{i=1}^n\sum_{j=1}^m\gcd(i,j)^2\)。根据 Luogu P4449 直接做即可。时间复杂度 \(\mathcal{O}(n+T\sqrt{n})\)。
\(\text{2025/5/9}\)
SPOJ 27942 PROD1GCD - Product it again
考虑线性筛出 \(f(n)=\prod_{d\mid n}\left(\frac{n}{d}\right)^{\mu(d)}\)。分类讨论:
-
\(n=p\):\(f(p)=p\)。
-
\(n=ip(p\not\mid i)\):
\[\begin{align*} f(ip)&=\prod_{d\mid i}\left(\frac{ip}{d}\right)^{\mu(d)}\times\prod_{d\mid i}\left(\frac{i}{d}\right)^{-\mu(d)}\\ &=\prod_{d\mid i}p^{\mu(d)}\\ &=1 \end{align*} \] -
\(n=ip(p\mid i)\):显然给 \(i\) 乘上 \(p\) 新增的因子在 \(p\) 处的指数必然 \(\geq 2\),因此不造成贡献。而对于 \(i\) 原有的因子,底数从 \(\frac{i}{d}\) 变为 \(\frac{ip}{d}\),总的变化量为 \(\prod_{d\mid i}p^{\mu(d)}=1\),因此此时 \(f(ip)=f(i)\)。
时间复杂度 \(\mathcal{O}(n+T\sqrt{n})\)。
\(\text{2025/5/10}\)
Luogu P3704 [SDOI2017] 数字表格
\(f(n)=\prod_{d\mid n}fib_d^{\mu\left(\frac{n}{d}\right)}\) 调和级数暴力预处理即可。时间复杂度 \(\mathcal{O}(n+T\sqrt{n})\)。
Luogu P3312 [SDOI2014] 数表
先不考虑值 \(\leq a\) 的限制,莫反:
加上 \(\leq a\) 的限制,我们发现相当于只保留 \(\sigma(d)\leq a\) 的部分。那么给询问离线,按 \(a\) 排序,同时把所有数按 \(\sigma\) 排序,扫描线,修改的时候暴力更新 \(f(n)=\sum_{d\mid n}\sigma(d)\mu\left(\frac{n}{d}\right)\) 的值,询问时需要查询区间和,上 BIT 维护 \(f\) 即可。时间复杂度 \(\mathcal{O}(n\log^2{n}+q\sqrt{n}\log{n})\)。
AtCoder ABC405E Fruit Lineup
对于 \(A,C,D\),要求 \(A\) 放在 \(C,D\) 的左边,随便做。考虑怎么插入 \(B\),发现我们需要知道最左边的 \(D\) 的位置。所以枚举在 \(A,C,D\) 构成的序列中最左边的 \(D\) 的位置 \(i\),这个的方案数就是在右边的 \(a+c+d-i\) 个空位中,选择 \(d-1\) 个位置放 \(D\) 的方案数,即 \(\binom{a+c+d-i}{d-1}\)。再来插入 \(B\),相当于 \(i\) 个空位插入 \(b\) 个板,一个空位可以插入多个板,这可太唐了,方案数为 \(\binom{i+b-1}{b}\)。因此答案为
预处理组合数即可。时间复杂度 \(\mathcal{O}(\max(a,b,c,d))\)。
AtCoder ABC405F Chord Crossing
显然线段 \((a,b)\) 和询问线段 \((c,d)\) 相交当且仅当 \(a<c<b<d\) 或 \(c<a<d<b\),分别扫描线即可。时间复杂度 \(\mathcal{O}(n\log{n})\)。
\(\text{2025/5/11}\)
Luogu P4240 毒瘤之神的考验
我们指出,
证明:
设 \(x=\prod_{i=1}^kp_i^{c_i}\),则定义 \(P(x)={p_1,p_2,\cdots,p_k}\)。根据定义展开 \(\varphi\):
\[\begin{align*} &\frac{\varphi(i)\varphi(j)\gcd(i,j)}{\varphi(\gcd(i,j))}\\ =&\frac{ij\gcd(i,j)}{\gcd(i,j)}\frac{\prod_{p\in P(i)}\frac{p-1}{p}\times\prod_{p\in P(j)}\frac{p-1}{p}}{\prod_{p\in P(\gcd(i,j))}\frac{p-1}{p}}\\ =&ij\prod_{p\in P(ij)}\frac{p-1}{p}\\ =&\varphi(ij)\quad\Box\\ \end{align*} \]
套用这个公式莫反:
令
则原式化为
\(f\) 不难 \(\mathcal{O}(n\log{n})\) 预处理出来。
容易看出 \(g\) 的递推关系:
而注意到我们需要的 \(g(kx)\) 都满足 \(kx\leq \max(n,m)\),因此直接递推求出所有 \(g\) 是可以接受的,时间复杂度为 \(\mathcal{O}(n\log{n})\)。
回到原式,考虑整除分块。不妨处理出前缀和,即令
那么整除分块的过程中,每次会计算出一个块 \([l,r]\),此时对答案的贡献为
然而处理出所有的 \(S\) 无法接受。考虑根号分治,设阈值 \(B\),对于所有 \(a,b\leq B\),预处理所有 \(S(a,b,x)(x\leq \left\lfloor\frac{\min(n,m)}{\max(a,b)}\right\rfloor)\)。整除分块时,当 \(\max\left(\left\lfloor\frac{n}{l}\right\rfloor,\left\lfloor\frac{m}{l}\right\rfloor\right)\geq B\),也即 \(l\leq\frac{\max(n,m)}{B}\) 时,暴力累加答案,否则用预处理出的前缀和计算即可。
根号分治部分的时间复杂度为 \(\mathcal{O}\left(B^2n+\frac{Tn}{B}\right)\),取 \(B=T^{\frac{1}{3}}\) 即可。时间复杂度 \(\mathcal{O}(n\log{n}+T^{\frac{2}{3}}n)\)。
Luogu P5572 [CmdOI2019] 简单的数论题
和 Luogu P4240 类似,令 \(g(k,n)=\sum_{i=1}^{n}\varphi(ik)\),直接 \(\mathcal{O}(n\log{n})\) 预处理出所有 \(g\)。此时原式化为
还是考虑预处理前缀和,令
根号分治,设阈值 \(B\),对于所有 \(a,b\leq B\),预处理所有 \(S(a,b,x)(x\leq \left\lfloor\frac{\min(n,m)}{\max(a,b)}\right\rfloor)\)。整除分块时,当 \(\max\left(\left\lfloor\frac{n}{l}\right\rfloor,\left\lfloor\frac{m}{l}\right\rfloor\right)\geq B\),也即 \(l\leq\frac{\max(n,m)}{B}\) 时,暴力枚举约数计算答案,否则用预处理出的前缀和计算即可。
整除分块的时间复杂度为
于是根号分治部分的时间复杂度为 \(\mathcal{O}\left(B^2n\log{n}+T\left(\frac{n}{B}\log\frac{n}{B}+\sqrt{n}\right)\right)\),取 \(B=T^{\frac{1}{3}}\) 即可。时间复杂度为 \(\mathcal{O}(T^{\frac{2}{3}}n\log{n}+T\sqrt{n})\)。
SPOJ 19985 GCDEX2 - GCD Extreme (hard)
欧拉反演:
其中 \(g(n)=\frac{n(n+1)}{2}\)。
整除分块,用杜教筛计算 \(\varphi\) 的前缀和即可。时间复杂度 \(\mathcal{O}(Tn^{\frac{2}{3}})\)。
SPOJ 26108 TRENDGCD - Trending GCD
其中 \(g(n)=\frac{n(n+1)}{2}\),\(f(n)=\sum_{d\mid n}\mu^2(d)d\mu\left(\frac{n}{d}\right)=\mu^2\operatorname{id}*\ \mu\)。显然 \(f\) 是积性函数,可以线性筛出,预处理 \(f\operatorname{id}^2\) 的前缀和,整除分块即可。时间复杂度 \(\mathcal{O}(n+T\sqrt{n})\)。
Luogu P5325 【模板】Min_25 筛
下文中令 \(\operatorname{lpf}(x)=\min_{p\mid x}p\),即 \(x\) 的最小质因子,\(p_k\) 表示第 \(k\) 小的质数。
Min_25 筛采用素数拟合的思路,我们分别考虑质数和合数处的 \(f\) 值之和。先来考虑
我们构造完全积性函数 \(F\),使得其在质数处的取值和 \(f\) 相等。那上式显然变成了
\(n\) 很大,我们不可能筛出所有 \(n\) 以内的质数。不妨考虑容斥,我们用 \(\sum_{i=1}^nF(i)\) 减去所有合数处的 \(F\) 的值,而所有合数 \(x\) 必然满足 \(\operatorname{lpf}(x)\leq\lfloor\sqrt{x}\rfloor\),所以我们考虑类似埃氏筛的思路,从小到大考虑每个 \(\lfloor\sqrt{n}\rfloor\) 以内的质数 \(p\),计算它们减掉的贡献。
由此考虑 DP。令
考虑如何从 \(g(n,x-1)\) 转移到 \(g(n,x)\),显然此时限制条件变强。不难发现去掉的恰好是那些 \(\operatorname{lpf}\) 为 \(p_x\) 的数,即
尝试刻画 \(\operatorname{lpf}(i)=p_x\) 的条件。注意到 \(F\) 是完全积性函数,我们可以提一个 \(F(p_x)\) 出来,这样子剩余部分应该满足 \(\operatorname{lpf}\geq p_x\)。考察 \(g\left(\left\lfloor\frac{n}{p_x}\right\rfloor,x-1\right)\),我们发现这仅仅多算了那些 \(<p_x\) 的质数处的 \(F\) 值之和。由于我们只考虑 \(\leq\lfloor\sqrt{n}\rfloor\) 的质数,所以不难预处理出 \(sp_x=\sum_{i=1}^xF(p_i)\)。于是我们得到了递推式:
根据杜教筛那一套理论,我们只需要 \(g\left(\left\lfloor\frac{n}{i}\right\rfloor,x\right)(p_x^2\leq \left\lfloor\frac{n}{i}\right\rfloor)\) 处的值,可以证明对这些点值 DP,时间复杂度是 \(\mathcal{O}\left(\frac{n^{\frac{3}{4}}}{\log{n}}\right)\) 的。
实现时,我们需要给 \(\left\lfloor\frac{n}{i}\right\rfloor\) 编号。这个挺典的,我们开两个 \(\mathcal{O}(\sqrt{n})\) 的索引数组 \(id_1\) 和 \(id_2\)。若 \(\left\lfloor\frac{n}{i}\right\rfloor\leq\sqrt{n}\),则将编号存在 \(id_1,\left\lfloor\frac{n}{i}\right\rfloor\) 中,否则令 \(j=\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor\),将编号存在 \(id_{2,j}\) 中即可。
注意我们最终只需要用到 \(g(n,\pi(\lfloor\sqrt{n}\rfloor))=\sum_{i=1}^n[i\in\mathbb{P}]F(i)\),因此 \(g\) 的第二维可以用滚动数组去掉。
回到原题,我们类似地设计 DP,令
还是分成质数和合数两部分考虑。对于前者,不难得出其贡献为
由于不保证 \(f\) 是完全积性函数,我们不能只提单个质因子出来,需要一次性全部提出。也就是我们先枚举 \(p_i(i>x)\),再枚举其指数 \(c\),这样就可以把 \(f(p_i^c)\) 提出来了。剩余部分应该满足 \(\operatorname{lpf}>p_i\),也就是 \(S\left(\left\lfloor\frac{n}{p_i^c}\right\rfloor,i\right)\),不过由于我们不把 \(1\) 纳入 \(S,g\) 的计算范围内,所以这样会漏掉 \(f(p_i^c\times 1)\),当 \(c=1\) 时,\(f(p_i)\) 我们已经在质数的部分计算过了,不用加回去,而当 \(c>1\) 时,我们则需要把 \(f(p_i^c)\) 加回去。由此得到递推式:
这部分的时间复杂度被证明是 \(\mathcal{O}(n^{1-\varepsilon})\) 的。
最终答案就是 \(S(n,0)+f(1)\)。
根据上面的过程,不难发现 Min_25 筛要求 \(f\) 和我们构造出的 \(F\) 具备以下性质:
- \(F(p)=f(p)\) 可以快速计算,\(F\) 的前缀和可以快速计算。
- \(f(p^c)\) 可以快速计算。
这些性质实际上是不难满足的。
注意我们实际上可以把 \(f(p)\) 分解成若干个完全积性函数 \(F(p)\) 的线性组合,在计算 \(S(n,x)\) 用到 \(\sum_{i=x+1}^{\pi(\lfloor\sqrt{n}\rfloor)}f(p_i)\) 时,用同样的方式线性组合对应的 \(g\) 和 \(sp\) 的值即可。
本题中 \(f(p)=p^2-p\),构造 \(F_1(p)=p\),\(F_2(p)=p^2\) 即可。
\(\text{2025/5/13}\)
Luogu P1587 [NOI2016] 循环之美
由于要求数值上互不相等,我们只需考虑所有最简分数。我们指出,最简分数 \(\frac{x}{y}\) 在 \(k\) 进制下是纯循环小数,当且仅当 \(\gcd(y,k)=1\)。
证明:
设 \(\frac{x}{y}\) 的循环节长度为 \(len\),显然 \(\frac{x}{y}\) 在 \(k\) 进制下是纯循环小数,等价于
\[\left\{\frac{x}{y}\right\}=\left\{\frac{xk^l}{y}\right\} \]其中 \(\{x\}\) 表示 \(x\) 的小数部分。
\(\{x\}=x-\lfloor x\rfloor\),据此化一下式子:
\[\frac{x}{y}-\left\lfloor\frac{x}{y}\right\rfloor=\frac{xk^l}{y}-\left\lfloor\frac{xk^l}{y}\right\rfloor\\ x-y\left\lfloor\frac{x}{y}\right\rfloor=xk^l-y\left\lfloor\frac{xk^l}{y}\right\rfloor\\ xk^l\equiv x\pmod{y}\\ k^l\equiv 1\pmod{y} \]因此 \(k\) 属于 \(y\) 的简化剩余系,即 \(\gcd(y,k)=1\)。\(\Box\)
于是题目转化为求
用莫反化一下 \([\gcd(i,j)=1]\):
其中 \(g(n)=\sum_{i=1}^n[\gcd(i,k)=1]\)。
由 \(\gcd(i,k)=\gcd(i\bmod{k},k)\),我们只需要 \(\mathcal{O}(k\log{k})\) 计算出所有 \(g(i)(1\leq i\leq k)\),对于 \(n>k\),我们有
这样就能 \(\mathcal{O}(1)\) 算出 \(g(n)\) 了。
对原式做整除分块。我们需要快速计算
还是用莫反化一下:
这样我们就得到了 \(f(k,n)\) 的递推式。记忆化一下,边界考虑 \(k=1\) 时 \(f(k,n)=\sum_{i=1}^n\mu(i)\),杜教筛计算即可。
时间复杂度 \(\mathcal{O}(\sqrt{n}\log{k}+n^{\frac{2}{3}})\)。
SPOJ 34096 DIVCNTK - Counting Divisors (general)
不难看出 \(f(n)=d(n^k)\) 是积性函数,且 \(f(p)=k+1\),\(f(p^c)=ck+1\),上 Min_25 筛,令 \(F=1\) 即可,后面再乘上 \(k+1\)。时间复杂度 \(\mathcal{O}(n^{1-\varepsilon})\)。
SPOJ 20174 DIVCNT3 - Counting Divisors (cube)
双倍经验 SPOJ 34096,令 \(k=3\) 即可。
SPOJ 20173 DIVCNT2 - Counting Divisors (square)
三倍经验 SPOJ 34096,令 \(k=2\) 即可。卡一下就过了。
SPOJ 7001 VLATTICE - Visible Lattice Points
简单分类,可以得出题目所求即为
这个拿脚莫反,变成
整除分块即可。时间复杂度 \(\mathcal{O}(n+T\sqrt{n})\)。
\(\text{2025/5/15}\)
Luogu P12393 「RiOI-6」flos
之前走直径的做法假完了,补一发正解。
我们的策略必然是先向上走一段,然后一直向下走。首先考虑一直向上走和一直向下走的情况,此时答案为 \(\max(dep_x-1,\min(f_x,t))\),其中 \(dep_1=1\),\(f_u\) 表示从点 \(u\) 向下走能走到的最远距离。
接下来令 \(g_u\) 表示从 \(fa_u\) 开始不经过 \(u\) 能走到的最远距离,则答案就是
拆 \(\min\):
- \(g_u\geq t\):我们只需取深度最小的 \(u\)。预处理 \(G_u\) 表示 \(u\) 到根节点的链上的 \(g\) 的最大值,树上倍增跳出深度最小的点 \(p\) 即可。
- \(g_u<t\):显然 \(u\) 必须是 \(v\) 的祖先,否则必然不优,于是预处理 \(h_u\) 表示 \(u\) 到根节点的链上的 \(g_v-dep_{fa_v}\) 的最大值即可。
时间复杂度 \(\mathcal{O}(n\log{n})\)。
\(\text{2025/5/16}\)
Codeforces 622F The Sum of the k-th Powers
Luogu P4593 [TJOI2018] 教科书般的亵渎
Luogu P5493 质数前缀统计
用 Min_25 筛的前半部分做 DP,边界 \(g(n,0)\) 是自然数幂和,直接 \(\mathcal{O}(k)\) 拉插即可。时间复杂度 \(\mathcal{O}\left(\frac{n^{\frac{3}{4}}}{\log{n}}+\sqrt{n}k\right)\)。
SPOJ 22549 DIVFACT4 - Divisors of factorial (extreme)
容易想到分别考虑每个 \([1,n]\) 中的质数 \(p\),经典地,\(n!\) 中 \(p\) 因子的个数是
因此
注意到对于 \(>\sqrt{n}\) 的 \(p\),它们都只有 \(1+\left\lfloor\frac{n}{p}\right\rfloor\) 的贡献,可以整除分块,这样对于一个块 \([l,r]\),计算出 \([l,r]\) 内的质数个数 \(cnt\),给答案乘上 \(\left(1+\left\lfloor\frac{n}{l}\right\rfloor\right)^{cnt}\) 即可。我们询问的端点都是形如 \(\left\lfloor\frac{n}{i}\right\rfloor\) 的位置,用 Min_25 筛的前半部分即可解决。这部分时间复杂度为 \(\mathcal{O}\left(\frac{n^{\frac{3}{4}}}{\log{n}}+\sqrt{n}\log{n}\right)\)。
而对于 \(\leq\sqrt{n}\) 的 \(p\),我们可以 \(\mathcal{O}(\log{n})\) 暴力跳,共有 \(\pi\left(\lfloor\sqrt{n}\rfloor\right)=\mathcal{O}\left(\frac{\sqrt{n}}{\log{n}}\right)\) 个这样的 \(p\),时间复杂度为 \(\mathcal{O}(\sqrt{n})\)。
由于模数 \(m\) 很大,需要上快速乘。
总时间复杂度为 \(\mathcal{O}\left(\frac{n^{\frac{3}{4}}}{\log{n}}+\sqrt{n}\log{n}\right)\)。
LOJ 6235 区间素数个数
上 Min_25 筛前半部分即可。时间复杂度 \(\mathcal{O}\left(\frac{n^{\frac{3}{4}}}{\log{n}}+\sqrt{n}\right)\)。
\(\text{2025/5/17}\)
SPOJ 19975 APS2 - Amazing Prime Sequence (hard)
对 Min_25 筛不那么裸的运用。
还是分开考虑质数和合数。对于质数,相当于求
这个 Min_25 筛随便做,令 \(F(p)=p\),做前半部分的 DP 即可。
对于合数,我们考察 Min_25 筛前半部分的 DP:
注意到 \(g\left(\left\lfloor\frac{n}{p_x}\right\rfloor,x-1\right)-sp_{x-1}\) 计算的就是 \(n\) 以内 \(\operatorname{lpf}=p_x\) 的数的个数,于是我们在 DP 过程中累加答案即可。
时间复杂度 \(\mathcal{O}\left(\frac{n^{\frac{3}{4}}}{\log{n}}+\sqrt{n}\right)\)。
AtCoder Xmas Contest 2019E - Sum of f(n)
Luogu P7884 【模板】Meissel-Lehmer
SPOJ 25024 NTHPRIME - Nth Prime
AtCoder ABC406C ~
A~F 这题想了最久……
根据题意,满足要求的序列必然是如下形式:
那么我们 \(\mathcal{O}(n)\) 找出序列中所有满足 \(a_{i-1}<a_i>a_{i+1}\) 或 \(a_{i-1}>a_i<a_{i+1}\) 的拐点 \(p\),枚举单峰拐点 \(p_i\) 作为上面的 \(a_{k_1}\),\(p_{i+1}\) 作为 \(a_{k_2}\),不难算出对应的方案数即为 \((p_i-p_{i-1})(p_{i+2}-p_{i+1})\),加到答案中即可。实现时要令 \(p_0\leftarrow 1,p_{sz+1}\leftarrow n\)。时间复杂度 \(\mathcal{O}(n)\)。
AtCoder ABC406D Garbage Removal
对每一行和每一列用 vector 存储当前行/列上的垃圾,对每个垃圾开一个 map 记录是否被清除,操作时遍历对应的 vector,累加答案,然后将对应的 vector 清空即可。时间复杂度 \(\mathcal{O}(n)\)。
AtCoder ABC406E Popcount Sum 3
一开始读成满足条件的数的个数了。没事,还是切了。
先不考虑 \(\leq n\) 的限制,这个很容易 DP 出来。令
即 \([0,2_i)\) 中所有 \(\operatorname{popcount}=j\) 的数之和。转移考虑低位起的 \(i-1\) 位填 \(0\) 还是 \(1\):
- 若填 \(0\),则满足要求的数之和为 \(f_{i-1,j}\)。
- 若填 \(1\),先不考虑当前位带来的贡献,则满足要求的数之和为 \(f_{i-1,j-1}\)。而当前位的贡献就是 \(2^{i-1}\) 乘上 \([0,2^{i-1})\) 中满足 \(\operatorname{popcount}=j-1\) 的数的个数,即 \(2^{i-1}\binom{i-1}{j-1}\)。
综上,可以得到转移方程:
初值令 \(f_{1,1}\leftarrow 1\) 即可。
回到原题,加上 \(\leq n\) 的限制,考虑正难则反,先令 \(ans\leftarrow f_{60,k}\),然后减去 \(>n\) 的 \(\operatorname{popcount}=k\) 的数之和。尝试刻画 \(x>n\) 的条件,从数位的角度考虑,我们从高到低遍历 \(x\) 的每一位,那么必然可以找到一个最高的位 \(i\),满足 \(x\) 的第 \(i\) 位为 \(1\),\(n\) 的第 \(i\) 位为 \(0\)。我们发现如果固定这个位 \(i\),那么 \(x\) 高于该位的部分必定和 \(n\) 相同,低于该位的部分则没有数位的限制,可以用我们处理出的 \(f\) 来计算总和。
于是从高到低枚举这个最高位 \(i\),设 \(n\) 的高于 \(i\) 位的部分中 \(1\) 的个数为 \(c\),则低于 \(i\) 位的部分的贡献就是 \(f_{i,k-c-1}\),不低于 \(i\) 位的贡献则是 \((num+2^i)\binom{i}{k-c-1}\),其中 \(num\) 表示 𝑛 的高于 𝑖 位的部分所代表的数。
这样就做完了。时间复杂度 \(\mathcal{O}(k^2)\)。
AtCoder ABC406F Compare Tree Weights
弱智题,BIT 维护 DFS 序,支持单点加、区间和即可。时间复杂度 \(\mathcal{O}(n\log{n})\)。

浙公网安备 33010602011771号