加载中...

2026杭电多校补题汇总

记录多校里值得补的题目。

1008

结合 SA 做数字串的最长上升子序列 dp,但一直卡常不知 hyw。。。

code

1001_

2-SAT

code

1007

数论与树上启发式合并相结合的 shu 论问题,可以用 gcd 容斥或莫比乌斯反演。

code_gcd容斥

code_莫比乌斯反演

1005

笛卡尔树相关问题,通过这道题进一步加深对笛卡尔树具体形态的印象。

code

1003

极角排序凸包 dp,写完 \(O(n^{4})\) 暴力 dp 后会发现还需要做一个环形前缀和优化 dp(就是破环成链再倍长后的序列 dp),使复杂度降至 \(O(n^{3})\)

code

1004_

期望计算

code

1012

树上计数题,需要自底向上传递信息,闭合子树需要动态删除。

code

1001_

2-SAT

1003

主要记录有关欧拉函数的经典恒等式:

\[\phi(mn)*\phi(\gcd(n,m)) = \phi(n)*\phi(m)*\gcd(n,m) \]

证明图片中也有。

还有狄利克雷前缀 \(\max\),其实就是关于 \(x\) 的所有约数取函数最大值。

pmXzylD.md.png

code

1006

数论推公式 + NTT 优化求和

\[f(n) = \sum_{i=1}^{n}\sum_{j=i}^{n}\sum_{k=i}^{j}\gcd(i,k)*\gcd(j, k)*C_{j}^{k} \]

观察三重求和,反映到对序列操作,可以发现是先枚举左端点,再枚举右端点,再枚举每一项

考虑用 \(f(n-1)\) 递推求 \(f(n)\),则 单独考虑右端点为 \(n\) 的情况

\[f(n) = f(n - 1) + \sum_{i=1}^{n}\sum_{k=i}^{n}\gcd(i,k)*\gcd(n,k)*C_{n}^{k} \]

令:

\[g(n) = \sum_{i=1}^{n}\sum_{k=i}^{n}\gcd(i,k)*\gcd(n,k)*C_{n}^{k} \]

问题等价于求解 \(g(n)\)

观察二重求和,反映到对序列操作,是先枚举左端点,再枚举右端点的形式。

而式子里包含仅含 \(k\) 的项,故我们可以考虑交换求和顺序,即先枚举右端点,再枚举左端点,进而把只包含 \(k\) 的项提出来:

\[g(n) = \sum_{k=1}^{n}(\gcd(n,k)*C_{n}^{k}*\sum_{i=1}^{k}\gcd(i,k)) \]

\(a_{n} = \sum_{i=1}^{n}\gcd(i, n)\),可以根据欧拉反演进一步化简:

\[a_{n} = \sum_{i=1}^{n}\sum_{d|\gcd(i,n)}\phi(d) \]

\[a_{n} = \sum_{i=1}^{n}\sum_{d|i,d|n}\phi(d) \]

将大条件 \(d|n\) 提到求和式最外层:

\[a_{n} = \sum_{d|n}\phi(d)*\sum_{i=1}^{n}[d|i] \]

显然 \(a_{1\backsim n}\) 可以 \(O(n\ln n)\) 预处理。

回到 \(g_{n}\)

\[g(n) = \sum_{k=1}^{n}\gcd(n,k)*C_{n}^{k}*a_{k} \]

仍将 \(gcd\) 用欧拉反演表示,并拆分组合数:

\[g(n) = (n!)\sum_{k=1}^{n}\frac{a_{k}}{(n-k)!*(k!)} * \sum_{d|k,d|n} \phi(d) \]

进一步化简:

\[g(n) = (n!)\sum_{d|n}\phi(d)*\sum_{d|k}\frac{a_{k}}{(n-k)!*(k!)} \]

看似可以预处理内部的求和式,实际上不能,因为这里 \(n\) 是变量,即内部求和式不是只关于 \(k\) 的式子,还与 \(n\) 有关。

观察得到,每个 \(d\) 仅对满足 \(d|i\)\(g(i)\) 有贡献,故我们可以考虑枚举 \(d \in [1, n]\),分别计算 \(d\)\(g(jd)\) 的贡献。

\(n = jd, k = pd\)

\[g(jd) = (jd)!\sum_{d|n}\phi(d)*\sum_{p=1}^{j}{a_{pd}}*infact_{jd-pd}*infact_{pd} \]

先不考虑 \(d\) 的影响,观察内部求和式:

\[b(j) = \sum_{p=1}^{j}{a_{p}}*infact_{j-p}*infact_{p} \]

\(A_{p} = a_{p} * infact_{p}\)\(B_{p} = infact_{p}\),容易发现 \(b_{j}\) 就是 \((A * B)_{j}\),即 \(A,B\) 做卷积后 \(x^{j}\) 项的系数。

仅将下标每一项乘 \(d\)

\[b(j) = \sum_{p=1}^{j}{a_{pd}}*infact_{jd-pd}*infact_{pd} \]

\(A_{p} = a_{pd} * infact_{pd}\)\(B_{p} = infact_{pd}\)(特殊地,\(p=0\) 时,令 \(A_{0}=0, B_{0}=1\);卷积求得的是 \(p=0\) 开始的结果,而二者是等价的),则卷积后 \((A*B)_{j}\) 恰好等于 \(b_{j}\)

于是每次枚举 \(d\) 时,处理出上述 \(A\)\(B\) 然后 NTT 求卷积,则 \(d\)\(g(jd)\) 的贡献即为 \(\phi(d) * (A*B)_{j}\)

由调和级数性质,所有多项式的总项数为 \(O(n\ln n)\),故总复杂度为 \(O(n\ln n *\log(n\ln n))\)

求出每个 \(g_{i}\) 后,其前缀和即为 \(f_{i}\)

code

1001

AC 自动机上 dp,需要一个 trick:对于一棵树,每个点有点权;给定一个点集,求从根结点到点集内每个点的所有路径的并集,包含的所有点的权值之和。这个可以用类似建虚树的方式来求:将点集内的所有点按照 dfn 序升排,然后求出每两个相邻点的 \(lca\)(所有的 \(lca\) 构成另一个点集);结合容斥原理,答案即为:原点集内所有路径权值之和 \(-\) \(lca\) 点集内所有路径权值之和。

code

1004_

树的重心 + 树哈希

code

1009

单调队列优化 dp。在转移需要用到 dp 数组上一层关于某一维度的 区间最值 时,可以用单调队列 + 滑窗的方式线性维护。

code

1003

根号分治 + 组合数隔板法扩展

code

1008_

MEX 结合树形 dp。

code

1003_

神秘树形 dp

code

1005_

笛卡尔树结合 KMP

code

1007_

随机化 + 哈希

code

1002_

第二类斯特林数

1003_

比较简单的网络流

1004

做法1:gcd容斥

赛时脑子抽了,想到了这种写法,但复杂度估计得不对。

显然 \(\gcd(a_{i}, k)\) 只可能是 \(k\) 的约数,因此只需要计算每种可能 \(\gcd\) 的贡献,即 \(i \in [l, r]\) 时,满足 \(\gcd(a_{i}, k) = g\)\(i\) 的数量,枚举 \(g\) 即可。

肯定能想到 \(\gcd\) 容斥,设上述值为 \(f_{g}\)\(i \in [l, r]\) 时,满足 \(a_{i}\)\(g\) 的倍数的 \(i\) 的数量为 \(cnt_{g}\),则:

\[f_{g} = cnt_{g} - \sum_{i=2}^{\inf} f_{i*g} \]

直接暴力枚举 \(i\) 显然会超时,但需要注意,只有在 \(x\)\(k\) 的倍数时,\(f_{x}\) 才有效,否则一定是 \(0\)。因此我们无须枚举 \(i\),只需要再枚举一层 \(k\) 的所有约数,并只将 \(g\) 的倍数转移过来。总复杂度 \(O(n\ln n + q * d^{2}(n))\)

code

做法2:莫比乌斯反演

求:

\[\sum_{i=l}^{r}(\gcd(a_{i}, k))^{2} \]

如果使用欧拉反演,最后会演化成求解欧拉函数和的平方形式,不好求解。这里尝试用莫比乌斯反演解决。

莫比乌斯反演,常用于解决 \(g(n) = \sum_{d|n}f(n)\),已知 \(g(n)\) 求解 \(f(n)\) 的情形。

这里令 \(g(n) = n^{2}\)

由莫比乌斯反演:

\[f(n) = \sum_{d|n}\mu(d)*g(\frac{n}{d}) \]

代入 \(g(n)\)

\[f(n) = \sum_{d|n}\mu(d)*(\frac{n}{d})^{2} \]

\(f(1 \backsim n)\) 可以通过 \(O(n\ln n)\) 预处理得到。

而原式即为:

\[\sum_{i=l}^{r} g(\gcd(a_{i}, k)) \]

展开得:

\[\sum_{i=l}^{r}\sum_{d|\gcd(a_{i},k)}f(d) \]

\[\sum_{i=l}^{r}\sum_{d|a_{i},d|k}f(d) \]

交换求和顺序:

\[\sum_{d|k}f(d)\sum_{i=l}^{r}[d|a_{i}] \]

对于每个查询,枚举 \(k\) 的约数 \(d\),并计算 \(a[l\backsim r]\)\(d\) 的倍数个数即可,后者可以 $vector + $ 二分解决。

总复杂度 \(O(n*\ln n + q*d(n)*\log n)\)

code

拓展得到 \(J_{k}(n)\) 函数

\[\sum_{d|n}J_{k}(d) = n^{k} \]

反演形式:

\[J_{k}(d) = \sum_{d|n}\mu(d)*(\frac{n}{d})^{k} \]

1005_

全局最小割板子

1006

“区间赋值 + 区间翻转” 线段树。维护双懒标记,区分 “先赋值再翻转” 与 “先翻转再赋值” 即可。

\(core:\) 打上赋值懒标记时需要清空翻转懒标记;打翻转懒标记时正常进行;下传懒标记时必须先下传赋值懒标记,再下传翻转懒标记。

code

1007

简单做法是 \(O(n\sqrt n \log n)\) 的,这里利用根号分块优化 \(\log\)

注意到变化量不是很大,可以很容易在莫队修改时做到 \(O(1)\)

code

posted @ 2026-08-14 17:01  小橘奏  阅读(12)  评论(0)    收藏  举报