2025.10 做题记录

2025.10 做题记录

10.1

CF1065G - Fibonacci Suffix (观察性质 + 逐位确定 + DP 刻画)

考虑逐位确定答案

设当前已确定的答案串为 \(\text{ans}\),先尝试在末尾拼个 0,统计 \(F(n)\) 中有多少个后缀 \(\le \text{ans}\)

考虑用 DP 刻画

\(f_i\) 表示 \(F(i)\) 中有多少个后缀 \(\le \text{ans}\);为辅助转移,再令 \(g_{i, j}\) 表示拼接 \(F(i), F(j)\) 时新产生多少个后缀 \(\le \text{ans}\)

显然有转移 \(f_{i} \leftarrow f_{i-2}+f_{i-1}+g_{i-2, i-1}\);问题只在于如何求出 \(g_{i-2, i-1}\)

P.S. 此处 " \(\le\) " 的定义为前 \(|\text{ans}|\) 位字典序 \(\le\)

注意到 \(|F(12)|, |F(13)| > 200\),当 \(i \ge 14\) 时,长度 \(\le m\) 的前 / 后缀不会跨过前两个串的连接处

这个性质的用处在于,拼接 \(F(i-1), F(i)\) 时 ( \(i-1 \ge 14\) ):

  • 新产生的 \(\le \text{ans}\) 的后缀的前 \(m\) 位在 \(F(i-1)\) 中的部分必定来自 \(F(i-2)\)
  • 新产生的 \(\le \text{ans}\) 的后缀的前 \(m\) 位在 \(F(i)\) 中的部分必定来自 \(F(i-2)\)
  • 综上,有 \(g_{i-1, i} = g_{i-2, i-2}\)

预处理 \(l_{12} = r_{12} = 12, l_{13} = r_{13} = 13\)\(l_i = l_{i-1}, r_i = r_{i-2}\ (i \ge 14)\),则 \(g_{i, j} = g_{l_i, r_j}\ (i, j \ge 14)\)

预处理 \(g_{12/13, 12/13}\)\(f_{12}, f_{13}\) 即可;单次时间复杂度 \(O(m^2)\),瓶颈在预处理

综上,当 \(n \le 13\) 时暴力求,反之 DP 即可;最终值 \(<k\) 则改为拼上 1\(>k\) 则拼上 0\(=k\) 则拼上 0 并输出

时间复杂度 \(O(nm^2)\),常数很小

CF587F - Duff is Mad (离线差分 + SA - 树状数组维护 \(\text{h}_i\) 连续段 + 根号分治)

套路的用特殊字符隔开全拼起来,建 SA 维护子串出现次数

先对询问离线差分,即将 \([l, r]\) 变为 \([1, r] - [1, l-1]\)

枚举串编号 \(i\),设其在总串中起始位置为 \(\text{st}_i\);考虑令 \(\text{h}_{\text{st}_i}\) 所在极长连续段区间 \(+1\),树状数组维护即可

法 1:查询 \(s_k\) 时,枚举 \(s_k\) 中每个位置 \(i\) 对应的 \(\text{rk}_i\),在树状数组中查询

法 2:开 vector 记录 \(s_k\) 中每个 \(\text{rk}_i\),每次二分在区间内的第 \(1\)\(\text{rk}_i\) 与最后 \(1\)\(\text{rk}_i\) 的位置 \(l, r\),累加 \(r-l+1\)

考虑根号分治;用法 1 解决 \(|s_i| \le B\) 的串,法 2 解决剩下的串

法 1 时间复杂度 \(O(qB \log n)\),法 2 时间复杂度 \(O(\frac{n^2 \log n}{B})\)

由于 \(n, q\) 同阶,取 \(B = \sqrt n\) 时最优,总时间复杂度 \(O((n+q) \sqrt n \log n)\)

CF1789F - Serval and Brain Power (分讨 - DP 求 LCP / 枚举贪心)

法 1:

考虑枚举分隔点,将串 \(s\) 分成 \(k\) 段,对 \(k\) 段同时 DP 求 \(\text{lcp}\)

时间复杂度 \(O(\binom{n}{k-1} n^k)\),很松

\(k \le 3\) 时,可以使用这个做法

法 2:

显然,\(\text{lcp}\) 必然被至少 \(1\) 个长为 \(\lceil \frac{n}{k} \rceil\) 的子串完全包含

枚举子串起点 \(i\),暴力 \(2^{\lceil \frac{n}{k} \rceil}\) 枚举后面的字符的选择状态,再从头贪心匹配 check 即可

时间复杂度 \(O(n^2 2^{\lceil \frac{n}{k} \rceil})\)

\(k \ge 5\) 时,可以使用这个做法

P.S. 容易发现 \(k\) 增大时,子串长度 \(\lceil \frac{n}{k} \rceil\) 减小,于是只需按照 \(k = 5\) 实现即可

注意到 \(k = 4\) 的情况完全包含于 \(k = 2\),那么做完了

10.2 - 10.3

摆烂 + 做 whk 作业

10.4

P12038 [USTCPC 2025] 送温暖 (分讨重心 + 子树分类 + meet in the middle)

看到 \(n \le 33\),考虑 meet in the middle

这启示我们分讨重心,因为以重心为根时子树大小 \(\le \frac{n}{2}\)

  • 当连通块不包含重心时,对每个子树 \(2^{\text{siz}}\) 暴力枚举即可

    这部分时间复杂度 \(O(n2^{\frac{n}{2}})\),很松

  • 当连通块包含重心时,有结论:必能将根的所有儿子划分为两集合 \(S, T\),使得 \(\max \{\sum\limits_{u \in S} \text{siz}_u, \sum\limits_{v \in T} \text{siz}_v\} \le \frac{2}{3}n\)

    \(\text{deg}_\text{rt} \le 3\) 时,由抽屉原理,必有一儿子 \(v\) 满足 \(\text{siz}_v \ge \frac{1}{3}n\);将 \(v\) 划分进 \(S\),其他划分进 \(T\) 即可

    \(\text{deg}_\text{rt} > 3\) 时,取出 \(\text{siz}\) 最小与次小的两儿子 \(v_1, v_2\),必有 \(\text{siz}_{v_1} + \text{siz}_{v_2} \le \frac{n}{2}\);合并 \(v_1, v_2\)\(\text{rt}\) 仍为重心,归纳证明即可

    按照如上过程将儿子分类,对一侧 \(2^\text{siz}\) 枚举所有含根连通块,用 set 维护

    暴搜另一侧,分讨是否需要 \(-m\),在 set 里 lower_bound 即可

    时间复杂度 \(O(n2^{\frac{2}{3}n})\)

综上,总时间复杂度 \(O(n2^{\frac{2}{3}n})\)

CF1552G - A Serious Referee (观察性质 - 只需对 01 序列满足 + 缩减状态 + 位运算)

注意到,"对任意 \(a_i\) 都能排序后都有序" 等价于 "对任意 \(01\) 序列排序后都有序":

  • 左推右,显然

  • 右推左,考虑对每个 \(x\),将 \(a_i\) 中的数根据其与 \(x\) 的大小关系赋为 \(0/1\)

    若排序后 \(0/1\) 数列有序,则对于 \(x\) 这一分界线满足要求

    若对任意 \(0/1\) 序列排序后都有序,则对任意 \(x\) 都满足要求,显然原数列有序

直接做是 \(O(n2^n)\) 的,考虑优化

注意到,我们每次无需重新枚举在之前的操作中已经枚举过了的位置

更进一步,对排序区间 \([l, r]\),只需知道 \([l, r]\)\(0/1\) 的个数就能确定排序后结果;因此只需枚举不确定位置中 \(1\) 的个数

P.S. 用 long long 压缩状态,可以用位运算 \(O(1)\) 得到排序后结果:

  • 预处理 \(T_i\) 表示第 \(i\) 次修改影响的位置集合,\(\text{pre}_i\) 表示前 \(i\) 次修改影响的位置集合

    因此,第 \(i\) 次修改时确定位置为 \(T_i \land \text{pre}_{i-1}\)

  • 预处理 \(l_{i, j}\) 强制使 \(S \land l_{i, j}\) 后第 \(i\) 次修改的前 \(j\) 个位置变成 \(0\),其余不变

    转移形如 \(l_{i, j} = l_{i, j-1} \oplus (2^k-1)\),初始值为 \(l_{i, 0} = (2^n-1)\)

    \(r_{i, j}\) 强制使 \(S \lor r_{i, j}\) 后第 \(i\) 次修改的后 \(j\) 个位置变成 \(1\),其余不变

    转移形如 \(r_{i, j} = r_{i, j-1} \lor (2^k-1)\),初始值为 \(r_{i, 0} = 0\)

    因此,设排序前所有位置中有 \(j\)\(1\),排序后只需令 \(S \leftarrow S \land l_{i, q_i-j} \lor r_{i, j}\) 即可

分析时间复杂度:

  • 设每轮不确定位置数为 \(a_1, a_2, \cdots, a_k\),显然有 \(\sum\limits_{i=1}^{k} a_i \le n\)
  • 我们希望最大化 \(\prod\limits_{i=1}^{k} (a_i+1)\);由基础不等式,有 \(\prod\limits_{i=1}^{k} (a_i+1) \le (\frac{\sum\limits_{i=1}^{k} (a_i+1)}{k})^k \le (\frac{n+k}{k})^k\)

综上,时间复杂度 \(O((\frac{n+k}{k})^k)\)

10.5

模拟赛

非常不熟的期望 DP + 第 \(1\) 步就想错的 T3,你不输谁输?

10.5 T1 - 汤圆的世界 (大模拟)

考虑先把必须挖的都挖掉

显然,对剩下的每个连通块,我们贪心地希望留下的方块尽量多,这样更容易满足限制

因此直接对整个连通块 check 即可;由于 \(1\) 个方块最多满足 \(3\) 个限制,单次 check 复杂度就是 \(O(\text{siz})\)

时间复杂度 \(O(n^3)\)

10.5 T2 - 玻璃走廊 (期望 DP)

显然,最优策略就是每次贪心地开面前第 \(1\) 个门,不断尝试向前走

注意到还剩多少个门要开对操作有影响,考虑将其刻画到状态里

\(f_{i, j}\) 表示走到位置 \(i\ (0 \le i \le n)\)\(i+1 \sim n\) 中还有 \(j\)1 (关着的门),走到终点的期望步数

注意到 0 的总数与 1 的总数是确定的,确定 \(i, j\) 后能算出前后各自 0 / 1 的数量,进而可知门 \(i+1\)0/ 1 的概率 \(P_0\)

具体的,令 \(\text{suf}_i\) 表示原本 \(i+1 \sim n\)1 的个数,\(\text{cnt}_0\) 表示 0 的总数,\(\text{cnt}_1\) 表示 1 的总数:

  • 若门 \(i+1\) 本来就是 1,则 \(P_0 = 0\)

  • 反之,则 \(i+1 \sim n\) 中原有 \(c_0 = n-i-\text{suf}_i\)0,需挑 \(c_1 = j-\text{suf}_i\) 个变成 1

    因此,更改后门 \(i+1\) 仍为 0 的概率为 \(P_0 = \frac{\binom{c_0-1}{c_1}}{\binom{c_0}{c_1}} = \frac{c_0-c_1}{c_0}\)

分讨转移情况:

  • \(i+1\)0,转移为 \(f_{i, j} \leftarrow f_{i+1, j} \cdot P_0\)

  • \(i+1\)1

    • 打开 \(i+1\) 后在前面关上;此时共有 \(\text{cnt}_0+1\)0 (包括新打开的 \(i+1\) ),前面有 \(i-(\text{cnt}_1-j)\)0

      因此,部分式子为 \(f_{i, j} \leftarrow (1+f_{i+1, j-1}) \cdot \frac{i-(\text{cnt}_1-j)}{\text{cnt}_0+1}\)

    • 打开 \(i+1\) 后刚好又关上了;部分式子为 \(f_{i, j} \leftarrow (1+f_{i, j}) \cdot \frac{1}{\text{cnt}_0+1}\)

    • 打开 \(i+1\) 后在后面关上;此时后面有 \(n-i-1-(j-1) = n-i-j\)0 (注意需舍掉 \(i+1\) )

      因此,部分式子为 \(f_{i, j} \leftarrow (1+f_{i+1, j}) \cdot \frac{n-i-j}{\text{cnt}_0+1}\)

    综上,完整的递推式为 \(f_{i, j} = (1+f_{i+1, j-1}) \cdot \frac{i-(\text{cnt}_1-j)}{\text{cnt}_0+1} + (1+f_{i, j}) \cdot \frac{1}{\text{cnt}_0+1} + (1+f_{i+1, j}) \cdot \frac{n-i-j}{\text{cnt}_0+1}\)

    移项可得 \(f_{i, j} = \frac{1}{\text{cnt}_0} \cdot ((1+f_{i+1, j-1}) \cdot (i-(\text{cnt}_1-j)) + 1 + (1+f_{i+1, j}) \cdot (n-i-j))\)

    转移时还需要乘上外层概率 \(1-P_0\)

    综上,为 \(f_{i, j} \leftarrow (1-P_0) \cdot \frac{1}{\text{cnt}_0} \cdot ((1+f_{i+1, j-1}) \cdot (i-(\text{cnt}_1-j)) + 1 + (1+f_{i+1, j}) \cdot (n-i-j))\)

初始值为 \(f_{n, i} = 0\),答案为 \(f_{0, \text{cnt}_1}\);实现上可以记忆化搜索,时间复杂度 \(O(n^2)\)

反思:期望 DP 需要加训!另外也别看到期望就害怕,还是可以尝试推一推的

10.5 T3 - 再见绘梨 (容斥 + DP)

看到 "出现次数 \(\ge 2\) ",首先考虑容斥

为什么要容斥?因为这样其他元素可以随意排,出现次数 \(\le 1\) 时也更容易统计

具体的,令 \(f_k\) 表示钦定 \(k\) 个元素只出现 \(\le 1\) 次,其他元素随便排的方案数

因此,答案为 \(\sum\limits_{i=0}^{n} (-1)^i \cdot \binom{n}{i} \cdot f_i \cdot 2^{2^{n-i}}\),后面的 \(2^{2^{n-i}}\) 表示由剩下 \(n-i\) 个元素挑一些组成的集合可以随便选

为方便推导,不妨令只出现 \(\le 1\) 的元素为 \(1, 2, \cdots, k\)

为刻画 \(1, 2, \cdots, k\) 的分配情况,再令 \(g_{i, j}\) 表示仅考虑 \(1, 2, \cdots, i\),将这 \(i\) 个数分配到 \(j\) 个集合中的方案数

因此,有 \(f_k \leftarrow \sum\limits_{i=0}^{k} g_{k, i} \cdot 2^{(n-k)i}\),后面的 \(2^{(n-k)i}\) 表示可将剩下 \(n-i\) 个数随意填充进集合中

\(g_{i, j}\) 的转移,考虑依次放入每个元素,有转移 \(g_{i, j} \leftarrow g_{i-1, j-1} + g_{i-1, j}(j+1)\) (新建集合 / 放入原有集合 / 扔掉当前元素)

初始值为 \(g_{i, 0} = 1\ (0 \le i \le n)\),即可以将所有元素全扔掉

时间复杂度 \(O(n^2 \log p)\),精细实现应该可以 \(O(n^2)\)

10.6

晚上打了 CF,又是战犯级挥发

10.5 T4 - 你、组乐队了吧 (正难则反 + 扫描线 + 线段树维护历史和)

同时维护两个条件是困难的,我们正难则反,考虑 \([l, r]\) 不合法的条件

显然,即为 \(\min\limits_{l \le x \le r} S_x \ne \min\limits_{l \le x \le r} M_x \lor \max\limits_{l \le x \le r} S_x \ne \max\limits_{l \le x \le r} M_x\);因此对 \(\min\)\(\max\) 分别考虑即可

\(\min\) 为例,考虑固定 \(\min\)\(v\),分析 \(S_i, M_i\) 各自区间的位置对答案的影响

\(\text{pos}_{1, v}, \text{pos}_{2, v}\) 表示值 \(v\)\(S_i, T_i\) 中的下标,\([l_{1, v}, r_{1, v}], [l_{2, v}, r_{2, v}]\) 表示以 \(v\) 作为最小值的,\(S_i, T_i\) 中的极长连续段

\(l_{1, v}, r_{1, v}, l_{2, v}, r_{2, v}\) 容易通过单调栈预处理出来,这部分时间复杂度 \(O(n)\)

考虑将限制刻画到二维平面上

\(v\)\(S_i\) 中对应所有 \((x, y)\ (x \in [l_{1, v}, \text{pos}_{1, v}],\ y \in [\text{pos}_{1, v}, r_{1, v}])\) 构成的矩形,在 \(T_i\) 中同理

显然,两矩形的交中的点满足 \(\min\) 的限制,其余点必不满足

考虑将两矩形中的点分别 \(+1\),交中的点 \(-2\),这样交中的点值为 \(0\),其余点均为 \(1\)

\(\min\)\(\max\) 分别做如上操作,最终值为 \(0\) 的点对应的区间即为合法区间

对查询 \([l, r]\),即计数所有 \((x, y)\ (x \in [l, r],\ y \in [l, r])\) 中值为 \(0\) 的点的数量

综上,需要支持矩形加 + 矩形查值为 \(0\) 的点的数量

考虑扫描线

具体的,考虑从 \(y\) 轴下 \(\rightarrow\) 上扫,每次 \(y\) 坐标 \(+1\),维护 \(x\) 轴上的区间

套路地,对矩形加操作即 \(\text{add}((l, r, u, d), c)\),差分为 " \(d\) 时进行 \([l, r]+c\) " 与 " \(u+1\) 时进行 \([l, r]-c\) "

类似的,对查询操作即 \(\text{query}(l, r, u, d)\),差分为 " \(u\) 时查询 \([l, r]\) 的答案" \(-\) " \(d-1\) 时查询 \([l, r]\) 的答案"

维护值为 \(0\) 的点的个数是困难的;不过容易发现 \(0\) 必为最小值,于是只需维护最小值 + 最小值个数

注意,我们不可能在每次 \(y\) 坐标 \(+1\) 时都对矩形对应的 \(x\) 轴区间做区间加;因此,需维护 \(x\) 轴区间的最小值个数的贡献次数

换句话说,就是维护区间内值为 \(0\) 的点的个数的历史和

综上,需要维护区间 \(\min\) ( \(\text{seg}\) ) + 区间 \(\min\) 出现次数 ( \(\text{cnt}\) ) + 历史和 ( \(\text{sum}\) ),支持区间加

考虑维护加法 tag ( \(\text{laz}\) ),对历史和再维护贡献次数 tag ( \(t\) )

实现细节:

  • pushup:正常 pushup 即可

  • pushdown:对 \(t\),若当前区间 \(\min\) 与子区间 \(\min\) 相等,则下传;反之不下传

    P.S. 下传即 \(t' \leftarrow t'+t\)\(\text{sum}' \leftarrow \text{sum}' + \text{cnt}' \cdot t\)

    对其他 tag 正常 pushdown 即可

  • update, get 等正常做即可

  • \(y\) 坐标 \(+1\) 后:

    • 首先,完成当前 \(y\) 坐标对应的区间加操作

    • 若全局 \(\text{seg}_{\text{root}}\)\(0\),令 \(t_{\text{root}} \leftarrow t_{\text{root}}+1\),且 \(\text{sum}_{\text{root}} \leftarrow \text{sum}_{\text{root}}+\text{cnt}_{\text{root}}\)

      反之,说明没有值为 \(0\) 的点,无需更新覆盖次数与历史和

    • 最后,完成当前 \(y\) 坐标对应的查询操作即可

时间复杂度 \(O(n \log n)\)

CF2045E - Narrower Passageway (期望转计数 + 拆式子 + 拆贡献)

显然,我们只需求出每种可能情况的贡献之和,最后除以 \(2^n\) 即可

考虑将式子拆为 \(m_1+m_2-m_1[m_1 = \max(m_1, m_2)]-m_2[m_2 = \max(m_1, m_2)]\)

对于前两项,以 \(+m_1\) 为例,拆贡献,枚举第 \(1\) 行中的每个位置 \(i\)

  • 单调栈 / 二分 + ST 表求出极长连续段 \([l, r]\),满足 \(\max\limits_{l \le k \le i} P_{1, k} = P_{1, i}\ \land\ \max\limits_{i+1 \le k \le r} P_{1, k} < P_{1, i}\)

  • 贡献即为 \(\sum\limits_{l'=l}^{i} \sum\limits_{r'=i}^{r} 2^{l'-2} \cdot 2^{n-r'-1} = (2^{i-1}-2^{l-2})(2^{n-i}-2^{n-r-1})\)

    P.S. 对 \(l=1\)\(r=n\) 的情况,可假装 \(2^{-1} = 0\)

对于后两项,以 \(-m_1[m_1 = \max(m_1, m_2)]\) 为例,仍然枚举第 \(1\) 行中的位置 \(i\)

此时极长连续段 \([l, r]\) 只需再满足一个 \(\max\limits_{l \le k \le r}P_{2, k} \le P_{1, i}\) 的限制即可

时间复杂度 \(O(n \log n)\)\(O(n)\)

P11674 [USACO25JAN] Reachable Pairs G (时光倒流 + 刻画操作 + 并查集)

删点不好做,考虑时光倒流变成加点

设第 \(i\) 个连通块的大小为 \(\text{siz}_i\),容易发现答案即为 \(\sum \frac{\text{siz}_i \cdot (\text{siz}_i-1)}{2}\)

对操作 \(1\),遍历点 \(u\) 的每个出边 \((u, v)\),若 \(v\) 已存在就用合并 \(u, v\) 所在连通块 + 更新答案

对操作 \(2\),容易发现对连通性没有影响,只造成连通块 \(\text{siz} \leftarrow \text{siz}+1\),更新 \(\text{siz}\) 与答案即可

注意,初始时操作 \(2\) 对应的点应视为 "已存在",只不过 \(\text{siz} = 0\)

P12028 [USACO25OPEN] Moo Decomposition G (观察性质)

注意到 "重复 \(L\) 次拼接" 是假的,不可能有 MOO...O 跨过连接处

证明:反证,考虑第 \(1\) 个串,若存在 MOO...O 跨过连接处则必然有 O 匹配不上 M,这个 O 即不合法;归纳易证

考虑如何求 \(S\) 的划分方案数

考虑由限制严到限制松,即从后向前匹配

维护当前 O 的个数 \(\text{cnt}\) 与答案 \(\text{ans}\)

  • \(s_i\)O,则 \(\text{cnt} \leftarrow \text{cnt}+1\)
  • \(s_i\)M,则 \(\text{ans} \leftarrow \text{ans} \cdot \binom{\text{cnt}}{K}\),且 \(\text{cnt} \leftarrow \text{cnt}-K\)

最终答案即为 \(\text{ans}^L\)

CF2145A - Candies for Nephews (模拟)

CF2145B - Deck of Cards (观察性质)

CF2145C - Monocarp's String (赋权 + 限制前缀和 + map)

10.7

P11842 [USACO25FEB] Bessie's Function G (刻画限制 + 基环树 DP)

连边 \(i \rightarrow a_i\),限制转化为 \(i\) 本身是自环 / \(i\) 连向一个自环

容易发现,若选择改变 \(a_i\),必然将 \(a_i\) 改成 \(i\) (即改成自环)

综上,对于每条原本的边 \((u, v)\),要求改动后 \(u, v\) 中至少 \(1\) 个是自环

容易发现这个限制与边的方向性无关,为方便 DP,可将所有有向边改成无向边

原图是一个基环树;考虑断环,再钦定断边两端点至少 \(1\) 个必选

\(f_{u, 0/1}\) 表示点 \(u\) 不改 / 改,子树内最小代价

转移显然为 \(f_{u, 0} \leftarrow \sum f_{v, 1}\)\(f_{u, 1} \leftarrow c_u+\sum \min(f_{v, 0}, f_{v, 1})\)

初始值为 \(f_{\text{leaf}, 0} = 0, f_{\text{leaf}, 1} = c_i\)

为实现方便,可分别强制断边端点为根,答案即为 \(f_{\text{root}, 1}\) (强制必选)

时间复杂度 \(O(n)\)

P12029 [USACO25OPEN] Election Queries G (刻画限制 + 双指针 + set + 观察性质)

\(c_i\) 表示 \(i\) 收到的票数,容易发现 \(i, j\ (i \ne j)\) 能成为领头牛的充要条件是 \(c_i+c_j \ge \max\limits_{1 \le k \le n} c_k\)

考虑 \(q = 1\) 怎么做

维护 \(l_v, r_v\) 表示满足 \(c_i = v\)\(i\) 的最小值 / 最大值

\(\text{mx} = \max\limits_{1 \le k \le n} c_k\),枚举 \(c_i = v\ (1 \le v \le n)\),则要求 \(c_j \ge \max(1, \text{mx}-v)\)

容易发现 \(v\) 增大时 \(\text{mx}-v\) 减小,令左端点为 \(l_v\),双指针维护最大右端点即可

将这个做法直接重复 \(q\) 次是 \(O(qn)\)

注意到 \(\sum c_i = n\),本质不同的 \(c_i\) 只有 \(\sqrt{n}\)

只枚举满足 \(c_i > 0\)\(c_i\),时间复杂度为 \(O(q \sqrt n)\)

所有信息均可用 set 维护,总时间复杂度 \(O(n \log n + q \sqrt n)\)

P11673 [USACO25JAN] Median Heap G (树形 DP + 观察性质 - 修改次数不超过 2)

考虑 \(q = 1\) 怎么做

直接的想法是令 \(f_{i, j}\) 表示操作完 \(i\) 子树,\(i\) 上填 \(j\) 的最小代价

问题是值域高达 \(10^9\),显然无法接受

注意到无需维护具体的数,只需维护与 \(m\) 的大小关系即可

\(f_{i, 0/1/2}\) 表示操作完 \(i\) 子树,\(i\) 上填的数小于 / 等于 / 大于 \(m\) 的最小代价

转移为 \(f_{u, \text{mid}(a, b, c)} \leftarrow f_{v_1, a}+f_{v_2, b}+w(u, c)\),其中 \(w(u, c)\) 表示将 \(a_u\) 变成对应状态的最小代价

初始值为 \(f_{\text{leaf}, c} = w(\text{leaf}, c)\),答案为 \(f_{1, 1}\),单次时间复杂度 \(O(n)\)

直接做 \(q\) 次是 \(O(nq)\) 的,无法接受

注意到 \(w(u, i)\) 最多被修改两次 ( \(m_i < a_u \land m_{i+1} \ge a_u\)\(m_i = a_u \land m_{i+1} > a_u\) 时)

将询问离线,按 \(m_i\) 从小到大排序;由于树高为 \(O(\log n)\),每次将修改的点的到根链拉出来,暴力跳父亲更新 DP 值就是对的

时间复杂度 \(O(n \log n)\)

10.8

模拟赛,但真的是 NOIP 模拟赛 (?

10.8 T1 - 乘积 (随机化性质 - 区间长度大于阈值时大概率合法 + 双指针)

20 pts:

考虑将 \(a_{t_1} \cdot a_{t_2} \cdot a_{t_3} \cdot a_{t_4} \equiv k\ (\bmod P)\) 对半分,转化为 \(a_{t_1} \cdot a_{t_2} \equiv \text{inv}(a_{t_3}) \cdot \text{inv}(a_{t_4}) \cdot k\ (\bmod P)\)

对每个询问 \(l, r\),枚举子区间,开桶维护 \(a_{t_1} \cdot a_{t_2}\ (\bmod P)\),查询 \(\text{inv}(a_{t_3}) \cdot \text{inv}(a_{t_4}) \cdot k\ (\bmod P)\) 是否出现过即可

时间复杂度 \(O(qn^2)\)

30 pts / 100 pts:

考虑怎么把复杂度里的 \(q\) 去掉

显然答案有单调性,对于每个 \(l\),求出最小的 \(r\) 使得 \([l, r]\) 合法即可

考虑双指针:

  • \(r' \leftarrow r+1\) 时,枚举 \(l \le i \le r'\),将 \(a_i \cdot a_r\ (\bmod P)\) 加入桶

    此时若状态从不合法变为合法,必有 \(t_4 = r\)

    枚举 \(t_3\),查询 \(\text{inv}(a_{t_3}) \cdot \text{inv}(a_{t_4}) \cdot k\ (\bmod P)\) 即可

  • \(l' \leftarrow l+1\) 时,枚举 \(l \le i \le r\),将 \(a_l \cdot a_i\ (\bmod P)\) 扔出桶

    此时若状态从合法变为不合法,必有 \(t_1' = l\)

    于是在移动 \(r\) 之前,先扫一遍判下即可

时间复杂度 \(O(n^2 + q)\)

注意到 \(a_i\) 随机,期望合法区间长度为 \(\sqrt[4]{P}\)

因此,我们总共扫过的距离不会很长,可以通过

时间复杂度 \(O(n \sqrt[4]{p})\)

反思:多观察单调性等信息,考虑预处理;数据随机时,考虑合法条件限制会较松 / 较严,一般与某个阈值有关

10.8 T2 - 简单环 (观察性质 + 贪心)

打表容易发现,\(x = x_0\) 时的答案等于 \(x = 1\) 时的答案乘 \(x_0\)

事实上这是符合直觉的;考虑将操作刻画为选择两点,起点 \(-1\),终点 \(+1\),代价为边权和

我们肯定希望按代价从大到小考虑,每次都操作到不能操作为止

考虑观察性质:

  • "以 \(u\) 为起点到 \(v\) " 等价于 "以 \(v\) 为起点到 \(u\) ",因为边权和为相反数

    一个点不能均作为起点 / 终点被操作两次,由贪心方案易知

  • 一个点不能既作为起点也作为终点被多次操作,因为这样不如将两次操作合并

    若两次操作合并后不优,说明这两次操作本身就不优

综上,一个点实际只会被操作一次

将 "代价为边权和" 转化为 "边权前缀和之差",问题即转化为对前缀和两两配对,使差的绝对值之和最大

由经典贪心,对前缀和排序后 \((1, n), (2, n-1), \cdots\) 配对即可

时间复杂度 \(O(n+q)\)

10.9

10.8 T3 - 追忆 (转化限制 - 求导刻画单调性 + 数位 DP 套 01 DP 优化完全背包)

先推推式子转化限制:

\[\begin{aligned} &\sum_{i=1}^{n} \sum_{j=1}^{n} \frac{a_i \cdot a_j \cdot \min\{X_i, Y_j\}}{c_i+c_j} \\ &= \sum_{i=1}^{n} \sum_{j=1}^{n} \frac{a_i \cdot a_j}{c_i+c_j} \cdot \frac{3 \cdot 3^{c_i+c_j}+2 \cdot (2^{c_i+c_j}-3^{c_j+c_j})+1 \cdot (1^{c_i+c_j}-2^{c_i+c_j})}{3^{c_i+c_j}} \\ &= \sum_{i=1}^{n} \sum_{j=1}^{n} \frac{a_i \cdot a_j}{c_i+c_j} \cdot \frac{3^{c_i+c_j}+2^{c_i+c_j}+1^{c_i+c_j}}{3^{c_i+c_j}} \\ &= \sum_{i=1}^{n} \sum_{j=1}^{n} \frac{a_i \cdot a_j}{c_i+c_j} \cdot (1^{c_i+c_j} + (\frac{2}{3})^{c_i+c_j}+(\frac{1}{3})^{c_i+c_j}) \end{aligned} \]

考虑定义 \(f(x) = \sum\limits_{i=1}^{n} \sum\limits_{j=1}^{n} \frac{a_i \cdot a_j}{c_i+c_j} x^{c_i+c_j}\),则原式为 \(f(1)+f(\frac{2}{3})+f(\frac{1}{3})\)

注意到分母上的 \(c_i+c_j\) 很烦,我们希望把它去掉,这样就能把 \(i, j\) 分离出来

注意到这与求导的性质相契合;这启示我们求导刻画函数的单调性:

\[\begin{aligned} f'(x) &= \sum_{i=1}^{n} \sum_{j=1}^{n} a_i \cdot a_j \cdot x^{c_i+c_j-1} \\ &= \frac{1}{x} \sum_{i=1}^{n} \sum_{j=1}^{n} (a_i \cdot x^{c_i}) \cdot (a_j \cdot x^{c_j}) \\ &= \frac{1}{x} (\sum_{i=1}^{n} (a_i \cdot x^{c_i}))^2 \end{aligned} \]

\(x > 0\) 时,\(f'(x) \ge 0\),因此有 \(f(x)\) 单调不降

注意到 \(f(0) = 0\),又因为 \(f(1)+f(\frac{2}{3})+f(\frac{1}{3}) = 0\),必然有 \(f(1) = 0, f(\frac{2}{3}) = 0, f(\frac{1}{3}) = 0\)

由此,可以得出 \(\forall x \in [0, 1],\ f'(x) = 0\);也就是说,对所有 \(v\),我们都有 \(\sum\limits_i [c_i = v]\ a_i = 0\)

显然对不同的 \(c_i = v\),限制条件是相同的;以下默认在所有 \(c_i\) 均相同的情况下考虑

整理下限制,为:

\[\begin{aligned} \sum_{i=1}^{n} a_i &= 0 \\ \sum_{i=1}^{n} (s_i+d_i \cdot t_i) &= 0 \\ \sum_{i=1}^{n} d_i \cdot t_i &= -\sum_{i=1}^{n} s_i \end{aligned} \]

注意到 \(-\sum\limits_{i=1}^{n} s_i\) 为定值,问题转化为完全背包,求刚好装到某个容量的方案数

由于 \(n \le 15,\ d_i \le 20,\ \sum\limits_{i=1}^{n} s_i \le 15 \cdot 10^{9}\),这其实是个特化的完全背包问题 (例题:CF1290F - Making Shapes )

这类问题的特点是物品数很小,容量很小,要装到的目标容量很大

对于这类问题,我们考虑在数位上做,每次确定所有 \(t_i\ (1 \le i \le n)\) 在当前位上的选择 ( \(0/1\) ),维护进位 + 与 \(s_i\) 的大小关系

具体的,令 \(f_{i, j, 0/1/2}\) 表示从低向高填到第 \(i\) 位,向后的进位为 \(j\),当前与 \(s_i\) 的低 \(i\) 位的大小关系为 \(<\) / \(=\) / \(>\) 的方案数

为什么从低到高?因为我们要维护进位,从低向高的进位不会影响低位的选择

考虑转移:

  • 朴素转移为暴力 \(2^n\) 枚举所有 \(t_i\) 当前位上填的 \(x_i\ (x_i \in \{0, 1\})\),则新产生的进位量为 \(k = \sum\limits_{i=1}^{n} [x_i = 1] t_i\)

    转移大概为 \(f_{i, j, 0/1/2} \rightarrow f_{i+1, \lfloor \frac{j+k}{2} \rfloor, 0/1/2}\) (对第三维,认为 \(i+1\) 位填 \((j+k) \land 1\),比较与 \(s_{i+1}\) 的大小关系即可)

    \(B = \log (\sum\limits_{i=1}^{n} s_i),\ D = \sum\limits_{i=1}^{n} d_i\),时间复杂度为 \(O(2^nqnDB)\)

  • 注意到确定 \(k = \sum\limits_{i=1}^{n} [x_i = 1] t_i\) 的过程实际上是 01 背包,考虑把 \(2^n\) 枚举的过程改成 01 背包

    \(g_{i, j}\) 表示对前 \(i\) 个物品做 01 背包,装出 \(j\) 的方案数;容易在 \(O(D)\) 的时间复杂度内求出 \(g_{i, j}\)

    预处理 \(g_{i, j}\),转移时枚举装到的容量 \(j\),时间复杂度为 \(O(qD^2B)\)

    注意到没必要枚举两次 \(D\),可将之前的 DP 值作为 01 背包的初值,每次转移都跑一遍 01 背包

    具体的,原本的初值为 \(g_{0, 0} = 1\),此时我们修改初值为 \(g_{0, j} = f_{i, j, 0/1/2}\),将初始的进位直接刻画到背包中

    时间复杂度 \(O(qnDB)\)

  • 考虑如何把时间复杂度里的 \(q\) 优化掉

    注意到修改改变的只有 \(\sum\limits_{i=1}^{n} s_i\),考虑把填成的状态 \(S\) 记到 DP 里

    \(S\) 多达 \(2^{34}\),存不下;考虑折半,记 \(B' = 17\),只存 \(B'\)\(S\)

    注意到影响后 \(B'\)\(S\) 转移的只有前 \(B'\) 位向后 \(B'\) 位的进位,于是查询时 \(O(D)\) 枚举进位即可

    实现上,无需每次枚举进位后重新 DP,设进位为 \(x\),则后 \(B'\) 位要填出的值即为 \((S\text{>>}17)-x\),直接查即可

    修改定义,令 \(f_{S, i, j}\) 表示前 \(i\) 位填出 \(S\),进位为 \(j\) 的方案数

    类似的,转移为 \(f_{S, i, j} \rightarrow f_{S \lor [(j +k) \land 1] 2^i, i+1, \lfloor \frac{j+k}{2} \rfloor}\)\(k\) 为 01 背包求出的新进位

    时间复杂度 \(O(2^{B'}nD+qD)\),可以通过

综上,时间复杂度 \(O(2^{B'}nD+qD)\)

10.12

P11843 [USACO25FEB] The Best Subsequence G (二分 + 分讨)

考虑先把修改变成互不相交的区间

对修改位置离散化 + 差分,将修改 \([l, r]\) 变成 \(a_l \leftarrow a_l \oplus 1\)\(a_{r+1} \leftarrow a_{r+1} \oplus 1\)

对离散化后的极长 \(1\) 连续段 \([l', r']\),其代表原区间 \([v_{l'}, v_{r'+1}-1]\)\(1\)

对查询 \([l, r]\),答案必为对最靠后的合法的 \(\text{pos}\),选择 \([l, \text{pos}]\) 中所有的 \(1\) 与后缀 \([\text{pos}+1, r]\)

先二分 \(\text{pos}\) 在哪个 \(1\) 连续段后,大力分讨,算出其在 \(0\) 连续段中的具体位置,最后计算答案

时间复杂度 \(O(n \log n)\)

细节一大堆,特别不好调……

10.13

P12031 [USACO25OPEN] Forklift Certified P (线段树 + dfs 求拓扑序)

\(M=2\)

显然,箱子 \(i\) 阻碍箱子 \(j\) 移走等价于箱子 \(i\) 的左下角在箱子 \(j\) 的右上角框出的矩形中

对所有箱子 \(i\)\(x_{i1}\) 排序,对 \(y_{i1}\) 建线段树,维护区间 \(\text{min}\)

查询 \(i\) 时,二分比 \(x_{i2}\) 小的第 \(1\) 个位置,查询前缀 \(\min\),判断是否 \(\ge y_{i2}\) 即可

删除箱子即为将对应的 \(y_{i1}\) 置为 \(+\infty\)

细节上,注意可能有自环,因此查询前需先将自身对应的 \(y_{i1}\)\(+\infty\)

时间复杂度 \(O(n \log n)\)

\(M=1\)

注意到,问题等价于对冲突的箱子对连有向边,求一组拓扑排序

考虑 dfs 求拓扑排序,依次尝试每个箱子:

  • 若没有箱子与其冲突,移走当前箱子
  • 如存在箱子与其冲突,dfs 这个箱子并把它移走;反复执行直到没有箱子与当前箱子冲突

\(M=2\) 的方式用线段树维护即可

容易发现每个点只会被删一次,时间复杂度 \(O(n \log n)\)

P11676 [USACO25JAN] DFS Order P (树形区间 DP + dfs 树性质)

考虑在 dfs 树上考虑

注意到,若 dfs 序为 \(1, 2, \cdots, n\),dfs 树的每个子树对应的 dfs 序必为连续区间,且根必为最小点

这启示我们每个子树是相同的子问题,考虑树形区间 DP

\(f_{l, r}\) 表示构造以 \(l\) 为根,dfs 序为 \([l, r]\) 的 dfs 树的最小代价

转移为 \(f_{l, r} \leftarrow f_{l, k} + f_{k+1, r} + \max(0, a_{l, k+1})\)

但这是不对的,因为我们没有考虑横叉边的影响

考虑修改定义为 \(f_{l, r}\) 表示构造以 \(l\) 为根,dfs 序为 \([l, r]\),且没有向 \(r+1 \sim n\) 的横叉边的 dfs 树的最小代价

则转移为 \(f_{l, r} \leftarrow \min(f_{l, k} + f_{k+1, r} + \max(0, a_{l, k+1}))+\sum\limits_{i=r+1}^{n} \max(0, -a_{l, i})\)

预处理后缀和,时间复杂度 \(O(n^3)\)

细节上,注意转移时将 \(l\) 为左端点的区间转移完再补上 \(\sum\limits_{i=r+1}^{n} \max(0, -a_{l, i})\),避免重复计算后面横叉边的代价

P11844 [USACO25FEB] Friendship Editing G (补图 + 状压 DP)

考虑原命题的逆否命题

即将 "若存在边 \((a, b)\),则必然存在 \((a, c)\)\((b, c)\) " 转化为 "若不存在 \((a, c)\)\((b, c)\),则不存在 \((a, b)\) "

这启示我们在补图上考虑,转化为 "若存在 \((a, c)\)\((b, c)\),则存在 \((a, b)\) "

容易发现,补图是许多点集不交的完全图的并

直接在补图上 DP,令 \(f_{S}\) 表示使 \(S\) 中的点符合要求的最小代价

预处理 \(g_{S}\) 表示使 \(S\) 中的点连成完全图的最小代价,\(h_{u, S}\) 表示去掉 \(u\)\(S\) 间的所有连边的最小代价

转移即为 \(f_{S} \leftarrow f_{T} + g_{S/T} + \sum\limits_{u \in S/T} h_{u, T}\)

直接做时间复杂度是 \(O(3^nn+2^nn^2)\)

注意到瓶颈在于 \(\sum\limits_{u \in S/T} h_{u, T}\),考虑把 \(T\) 带来的影响去掉,直接去掉 \(S/T\) 中的点与其他所有点的连边

这样相当于强制每条边拆 \(2\) 次,同时把 \(g_S\) 中加一条边的代价改成 \(2\),最后答案除以 \(2\) 即可

初始值为 \(f_{S} = +\infty, f_0 = 0\),答案为 \(f_{2^n-1}\)

时间复杂度 \(O(3^n + 2^nn^2)\)

10.14

P11847 [USACO25FEB] True or False Test P (观察性质 + 贪心 + 类决策单调性分治)

考虑先让 Bessie 选若干道题目获得 \(\sum a_i\) 的得分,再让 Elsie 选 \(k\) 道减去 \(\sum (a_i + b_i)\)

容易发现,按 \(a_i+b_i\) 从大到小排序,Elsie 必然会扣掉 Bessie 选的前 \(k\) 道题

P.S. 临项交换同样能够导出这一结论

枚举分界点 \(i\),则 Bessie 希望贪心地在 \([1, i]\) 中选 \(k\) 个使得 \(\sum b_j\) 最小,\([i+1, n]\) 全选,最大化 \(\sum\limits_{j > i} a_j - \min \sum b_j\)

注意到 \(k \rightarrow k+1\) 时,最优决策点不会左移:

  • 若左移,设原决策点为 \(i_1\),现决策点为 \(i_2\),当前方案中必有至少 \(1\)\(j \in [1, i_2]\) 使得 \(j\)\([1, i_1]\) 中未选
  • 容易发现,不改变其他选择,直接在 \(k\) 时的决策中选上 \(j\) 必然比当前更优

那么类似决策单调性优化 DP,分治解决即可

实现上可以上主席树维护 \(\min \sum b_j\)

时间复杂度 \(O(n \log^2 n)\)

10.15

P11845 [USACO25FEB] Min Max Subarrays P (打表找规律 + 分讨 + 容斥)

打表发现,\(\text{len} \ge 7\)\(\text{len}\) 为奇数时答案必为最大值,\(\text{len} \ge 8\)\(\text{len}\) 为偶数时答案必为次大值

对每个点,维护 \(\text{ls}_i, l_i, r_i, \text{rs}_i\) 表示左 / 右第 \(1\) / \(2\) 个大于当前数的数的位置

枚举 \(i\),拆贡献:

  • \(i\) 为最大值的贡献为选择 \(l \in [l_i, i], r \in [i, r_i]\),满足 \(r-l+1\) 为奇数的方案数

    \(\text{len} \ge 7\) 的选择方案可以直接容斥掉;最后别忘了乘 \(a_i\)

  • \(i\) 为次大值的贡献为选择 \(l \in (\text{ls}_i, l_i], r \in [i, r_i)\)\(l \in (l_i, i], r \in [r_i, \text{rs}_i)\),满足 \(r-l+1\) 为偶数的方案数

    同理,对 \(\text{len} \ge 8\) 容斥,最后乘 \(a_i\)

\(n \le 6\) 的部分,枚举排列,记忆化暴搜即可

时间复杂度 \(O(n \log n)\)

P12032 [USACO25OPEN] Lazy Sort P (观察性质 + 划分连续段 + 组合数学)

打表发现,序列合法的充要条件是不存在逆序对 \((i, j)\),使得 \(i < j\)\(a_i-a_j \ge 2\)

考虑将满足 \(\forall i \in [l, r],\ a_i = a_l \lor a_i = a_l-1\) 的极长连续段 \([l, r]\) 划分出来

我们称 \(a_l\) 为连续段 \([l, r]\) 的标志值,容易发现 \(a_l\) 单增

一种想法是 DP,将 \(a_l\) 记到状态里,容易做到 \(O(nV^2)\);不过这是没有前途的

考虑 \(q = 2\) 怎么做

\(\text{calc}(\text{len}, x, y)\) 表示长为 \(\text{len}\),首位所在连续段的标志值为 \(x\),末位所在连续段的标志值为 \(y\),中间的填法数

考虑如何求 \(\text{calc}(\text{len}, x, y)\)

  • 先判掉 corner case:

    • \(x > y\),方案数为 \(0\)
    • \(\text{len} = 1\),方案数为 \([x = y]\)
    • \(x = y\),方案数为 \(2^{\text{len}-1}\) (首位必填 \(x\),后面随便填)
  • 枚举 \(c\ (2 \le c \le \min(y-x+1, \text{len}))\),表示我们要将其划为 \(c\)

  • 考虑分配断点,贡献为 \(\binom{\text{len}-1}{c-1}\)

  • 考虑分配段标志值,贡献为 \(\binom{y-x+1}{c-2}\) (首尾已确定)

  • 对每段,设标志值为 \(v_i\),长度为 \(l_i\),首位必填 \(v\),其余位置有填 \(v\)\(v-1\) 两种方案

    因此,贡献为 \(2^{\sum (l_i-1)} = 2^{\text{len}-c}\)

  • 综上,总方案数为 \(\sum\limits_{2 \le c \le \min(y-x+1, \text{len})} \binom{\text{len}-1}{c-1} \cdot \binom{y-x+1}{c-2} \cdot 2^{\text{len}-c}\)

    P.S. 实现上,注意到组合数连续,每次求新的组合数时上下补乘一位即可

考虑推广到原问题

\(f_{i, 0/1}\) 表示考虑到第 \(i\) 个关键点,当前标志值为 \(v_i\) / \(v_i+1\) 的方案数

转移为:

  • \(\text{len} = c_{i}-c_{i-1}+1,\ x = v_{i-1},\ y = v_i\)

  • \(f_{i-1, 0}\) 转移至 \(f_{i, 0}\) 时,系数为 \(x_{00} = \text{calc}(\text{len}, x, y)-\text{calc}(\text{len}-1, x, y)\)

    后面减去的部分代表去掉末位填 \(v_{i}-1\) 而非 \(v_i\) 的贡献

  • \(f_{i-1, 0}\) 转移至 \(f_{i, 1}\) 时,系数为 \(x_{01} = \text{calc}(\text{len}-1, x, y+1)\)

    \(\text{len}-1\) 代表强制末位填 \(v_i\)

  • \(f_{i-1, 1}\) 转移至 \(f_{i, 0}\) 时,系数为 \(x_{10} = \text{calc}(\text{len}, x+1, y)-\text{calc}(\text{len}-1, x+1, y)\),原因同上

  • \(f_{i-1, 1}\) 转移至 \(f_{i, 1}\) 时,系数为 \(x_{11} = \text{calc}(\text{len}-1, x+1, y+1)\),原因同上

  • 综上,有转移:

    • \(f_{i, 0} \leftarrow x_{00} \cdot f_{i-1, 0} + x_{10} \cdot f_{i-1, 1}\)
    • \(f_{i, 1} \leftarrow x_{01} \cdot f_{i-1, 0} + x_{11} \cdot f_{i-1, 1}\)

初始值为 \(f_{0, 0} = 1, f_{0, 1} = 0\);答案为 \(f_{q, 0} + f_{q, 1}\)

时间复杂度 \(O(n)\)

10.16

P12030 [USACO25OPEN] OohMoo Milk G (贪心 + 拆分过程 + 二分)

贪心地,由于使较大的 \(m_i\)\(1\) 对现在及以后的答案增量影响更大:

  • John 必然选择使前 \(A\) 大的 \(m_i\)\(1\)
  • Nhoj 必然选择使前 \(B\) 大的 \(m_i\)\(1\)

按初始 \(m_i\) 从大到小排序,容易发现只有前 \(A\) 个会被操作到,后面的可以扔掉

Nhoj 每次选择的位置可能变化,我们不好维护;但注意到 John 每次必然执行全局加,于是考虑将加和减的过程拆分

具体的,先对所有 \(1 \le i \le A\) 执行 \(m_i \leftarrow m_i+D\),再让 Nhoj 选择一些位置减少:

  • 设 Nhoj 让 \(m_i\) 减少了 \(c_i\),显然有 \(c_i \le D\)
  • 同时,还要满足 \(\sum c_i = B \cdot D\)

考虑将所有 \(m_i\) 按在最终方案中减完 / 没减完 \(D\) 次分类:

  • 考虑二分 \(\text{mid}\),代表所有没减完 \(D\) 次的 \(m_i\) 中,减完后剩余容量的最大值
  • 考虑如何 check:
    • \(m_i-D \ge \text{mid}\),直接减完 \(D\),令代价 \(w \leftarrow w+D\)

    • 反之,令 \(w \leftarrow w+m_i-\text{mid}\)

    • \(w > B \cdot D\),说明不合法

    • 反之合法,从大到小考虑每个没减完 \(D\) 次的 \(m_i\) 并将其改为 \(m_i-1\),直到剩余次数用完为止

      P.S. 改到 \(m_i-2\) 及以下的方案会在 \(\text{mid}\) 更小时考虑到

时间复杂度 \(O(n \log V)\)

10.17

P11678 [USACO25JAN] Watering the Plants P

10.18

P11678 [USACO25JAN] Watering the Plants P (slope trick + 平衡树)

首先,容易得到 \(O(nV^2)\) 的 DP 做法

\(f_{i, j}\) 表示使用前 \(i-1\) 条水渠,前 \(i-1\) 个植物满足要求,且第 \(i\) 个植物水量为 \(j\) 的最小代价

转移显然有 \(f_{i, j} \leftarrow \min\limits_{k \ge \max(w_{i-1}-j, 0)} f_{i-1, k} + c_{i-1} \cdot j\)

初始值为 \(f_{1, 0} = 0\),其余为 \(+\infty\);询问 \(i\) 的答案为 \(\min\limits_{j \ge w_i} f_{i, j}\)

维护后缀 \(\min\) 可以优化到 \(O(nV)\)

我们大胆猜测当 \(i\) 不变时,\(f_{i, j}\) 是凸的

证明如下:

  • 注意到当 \(i \leftarrow i+1\) 时,我们实际上干的事是:
    • 取后缀 \(\min\)
    • \([0, w_{i-1}]\) 翻转
    • \((w_{i-1}, V]\) 推平为全局 \(\min\)
    • 累加上斜率为 \(c_{i-1}\) 的一次函数
  • \(i = 1\) 时,\(f_{i, 0} = 0\),其余为 \(+\infty\)
  • \(i = 2\) 时,\([0, w_1)\)\(+\infty\)\([w_1, V]\) 为起点在 \((w_1, c_1w_1)\),斜率为 \(c_1\) 的一次函数
  • \(i = 3\) 时,分类讨论:
    • 取后缀 \(\min\) 相当于将 \([0, w_1)\) 推平成 \(c_1w_1\)\([w_1, V]\) 不变

    • \(w_2 \le w_1\)

      • 翻转相当于啥也没干
      • \((w_2, V]\) 会被推平成 \(c_1w_1\)
      • 最终即在水平线 \(y = c_1w_1\) 上累加一次函数

      综上,会形成起点在 \((0, c_1w_1)\),斜率为 \(c_2\) 的一次函数

    • \(w_2 > w_1\)

      • 原本
        \([0, w_1)\) 为水平线 \(y = c_1w_1\)\([w_1, w_2]\) 内为起点在 \((w_1, c_1w_1)\),斜率为 \(c_1\) 的一次函数

      • 翻转后 \([0, w_2-w_1]\) 为起点在 \((0, c_1w_2)\),斜率为 \(-c_1\) 的一次函数

        \((w_2-w_1, w_2]\) 为水平线 \(y = c_1w_1\)

      • \((w_2, V]\) 会被推平为 \(c_1w_1\)

      • 最终再累加一次函数

      综上,\([0, w_2-w_1]\) 为起点在 \((0, c_1w_2)\),斜率为 \(c_2-c_1\) 的一次函数

      \((w_2-w_1, V]\) 为起点在 \((w_2-w_1, c_1w_1+c_2(w_2-w_1))\),斜率为 \(c_2\) 的一次函数

    • 综上,不难发现 \(i = 3\) 时函数必定是下凸的

  • \(i > 3\) 时,令 \(f_{i-1, j}\) 中第一个最小值点的 \(x\) 坐标为 \(\text{mn}\),分类讨论:
    • 取后缀 \(\min\) 相当于将 \([0, \text{mn}]\) 推平成原最小值,\((\text{mn}, V]\) 不变

    • \(w_{i-1} \le \text{mn}\)

      • 翻转相当于啥也没干
      • \((\text{mn}, V]\) 会被推平为原最小值
      • 最终即在水平线上累加一次函数

      综上,此时退化为一次函数,仍是下凸的

    • \(w_{i-1} > \text{mn}\)

      • 翻转相当于将 \([\text{mn}, w_{i-1}]\) 翻转并移到最前面
      • \((\text{mn}, V]\) 会被推平为原最小值
      • 最终再累加一次函数

      发现累加一次函数很烦,我们考虑在差分 (斜率) 序列上分析,变为全局斜率加

      由于 \(f_{i-1. j}\) 下凸,原 \((\text{mn}, w_{i-1}]\) 的斜率恒正且不降,翻转并取反后恒负且不降

      由于这段被移动到了最前面,此时斜率序列应先恒负且不降,后面全是 \(0\);整体是单调不降的

      最终全局加不影响凹凸性

      因此,我们能够证得当前函数仍下凸

    • 综上,\(f_{i, j}\) 仍是下凸的

通过上述证明,我们发现 \(i > 3\)\(f_{i, j}\) 是下凸的;\(i \le 3\) 时暴力 DP 即可

考虑直接用平衡树按照证明过程维护差分序列,需要支持:

  • 区间翻转并取反
  • 将区间移到最前面
  • 区间推平为 \(0\)
  • 全局加
  • 查询区间和

FHQ-Treap 维护即可,实现上需要维护翻转并取反 tag,推平 tag,加法 tag 共三个 tag

由证明,差分序列单调不降,且必为负 $\rightarrow 0 \rightarrow $ 正的形式 (当然也可能恒非负)

因此,可以直接对 \(0\) 按值分裂求出第一个最小值点的位置

实现时需要手动查询全局 \(\min\) 维护 \(f_{i, 0}\)

时间复杂度 \(O(n \log V + V)\)

10.21

P11846 [USACO25FEB] Transforming Pairs P (观察性质 + 分类讨论)

P.S. 为方便分析,以下令 \((a, b), (c, d)\) 为平面直角坐标系中的点

先考虑 \(a, b, c, d \ge 0\) 怎么做

注意到由 \((c, d)\) 倒推的过程是确定的,即为辗转相除

在平面直角坐标系上,辗转相除即为 \((c, d) \rightarrow (x', 0) / (0, y')\) 的过程,\(x > y\) 时向左走,反之向下走

模拟行走过程,对每条横线 / 竖线判断 \((a, b)\) 是否被经过即可

特殊地,当 \(x \equiv 0\ (\bmod\ y)\ (x \ge y)\) 时:

  • 可以 \((x, y) \rightarrow (0, y)\),因此 \(a = 0, b = y\) 时成立
  • 可以 \((x, y) \rightarrow (y, y) \rightarrow (y, 0)\),因此 \(a = y,\ b = 0\) 时也成立

注意到 \(a, b, c, d\) 全部取反 / 交换 \(a, b\) 并交换 \(c, d\) 后答案不变

\(a, b\) 同号时,可调整到 \(a, b \ge 0\)

  • \(c < 0\)\(d < 0\),无解
  • 反之,用 \(a, b, c, d \ge 0\) 的方法解决即可

\(a, b\) 异号时,可调整至 \(a > 0, b < 0\);先考虑 \(c, d\) 异号的情况:

  • 注意到 \(a\) 变号 / \(b\) 变号后就不可能再变回来,因此 \(c < 0, d > 0\) 时无解
  • \(a, c\) 同号,\(b, d\) 同号时:
    • \((a, -|b|) \rightarrow (a-|b|, |b|)\ (a \ge |b|)\) 可等价到 \((a, |b|) \rightarrow (a-|b|, |b|)\)
    • \((a, -|b|) \rightarrow (a, a-|b|)\ (a \le |b|)\) 可等价到 \((a, |b|) \rightarrow (a, |b|-a)\)
    • 注意到这就是将 \(y\) 取反,由 \((a, |b|)\) 倒推的过程,现答案等于 \((c, |d|) \rightarrow (a, |b|)\) 的答案

再考虑 \(c, d\) 同号的情况,此时可调整至 \(a > 0, b < 0, c \ge 0, d \ge 0\)

  • 由于只能从 \(x\) 轴下跳到上 \(1\) 次,考虑倒推 \((c, d) \rightarrow (0, 0)\),正推 \((a, -|b|) \rightarrow (0, 0)\),考察怎样跳上来合法
  • 当正推至 \((x, -|y|)\ (x \ge |y|)\) 时,可能跳到 \((x, x-|y|)\);显然只能从横线上的点向上跳
  • 推广到 \((x, -|y|) \rightarrow (x', -|y|)\) 的横线:
    • 其经过的点为 \((x, -|y|), (x-|y|, -|y|), \cdots, (x-k|y|, -|y|)\ (x-k|y| \ge |y|)\)
    • 能向上跳到的点为 \((x, x-|y|), (x-|y|, x-2|y|), \cdots, (x-k|y|, x-(k+1)|y|)\)
    • 注意到,这些点都在 \(f(p) = p-|y|\) 上,且不能跳到竖线上 ( 因为 \(x-k|y| \ge x-(k+1)|y|\) )
    • 贪心地,从高到低枚举 \((c, d) \rightarrow (0, 0)\) 的横线 \((x_0, y_0) \rightarrow (x_0', y_0)\) (倒推):
      • 算出起跳点 \((p, -|q|)\)
      • 维护 \((a, -|b|) \rightarrow (x, -|y|)\) 的贡献
      • 算出 \((x, -|y|) \rightarrow (p, -|q|)\) 的贡献
      • \((p, -|q|) \rightarrow (p, p-|q|)\) 的贡献为 \(1\)
      • 算出 \((p, p-|q|) \rightarrow (x_0, y_0)\) 的贡献
      • 维护 \((x_0, y_0) \rightarrow (c, d)\) 的贡献
      • 累加,更新答案即可
    • 特殊地,当 \(x \equiv 0\ (\bmod\ |y|)\) 时:
      • 可以 \((x, -|y|) \rightarrow (|y|, -|y|) \rightarrow (|y|, 0)\)
      • 此时直接用 \(a, b, c, d \ge 0\) 的方法算即可
    • 别忘了考虑从 \((c, d)\) 倒推到 \((a, b) \rightarrow (0, 0)\) 的终点的贡献

时间复杂度 \(O(n \log^2 V)\)

10.22

P11677 [USACO25JAN] Shock Wave P (观察性质 - 调整法 + 分析变化量 + 优先队列)

以下坐标从 \(1\) 开始

打击 \(x_0\) 一次,相当于施加一个与 \(x\) 轴交点为 \(x_0\) 的绝对值函数

注意到若存在两次打击点为 \(i, j\ (1 < i, j < n)\),调整为 \(i-1, j+1\) 可使两侧变化量相同且中间增大,必定不劣

因此,在 \((1, n)\) 中的打击点至多有 \(1\)

先考虑打击点全为 \(1\)\(n\) 时,如何确定答案:

  • 二分答案 \(\text{ans}\),不妨设 \(1\) 操作 \(a\) 次,\(n\) 操作 \(b\) 次,有 \(a+b = \text{ans}\)

  • 对位置 \(i\),要求 \(p_i \le a(i-1)+b(n-i)\)

  • \(2i-1 < n\) 时,移项:

    \[\begin{aligned} &p_i \le (a+b)(i-1)+b(n-2i+1) \\ &p_i-(a+b)(i-1) \le b(n-2i+1) \\ &b \ge \frac{p_i-(a+b)(i-1)}{n-2i+1} \end{aligned} \]

  • \(2i-1 > n\) 时,同理移项:

    \[\begin{aligned} &p_i \le (a+b)(n-i)-a(n-2i+1) \\ &a \ge \frac{p_i-(a+b)(n-i)}{2i-1-n} \end{aligned} \]

  • \(2i-1 = n\) 时,特判即可

  • \(O(n)\) 维护 \(a, b\)\(\max\),判断加起来是否超过 \(\text{ans}\) 即可

  • 时间复杂度 \(O(n \log V)\)

注意到,只考虑 \(1, n\)\(\text{ans}\) 至多比真正的 \(\text{ans}\)\(1\),只需检验 \(\text{ans}-1\) 是否成立即可

\((1, n)\) 中的操作位置为 \(m\),则我们需要维护:

\[\begin{aligned} \max_{2i-1 < n}\ (\frac{p_i-(a+b)(i-1)}{n-2i+1}-\frac{|m-i|}{n-2i+1}) \\ \max_{2i-1 > n}\ (\frac{p_i-(a+b)(n-i)}{2i-1-n}-\frac{|m-i|}{2i-1-n}) \end{aligned} \]

对位置 \(i\),当操作位置 \(m\) 变化时,\(\max\) 的变化量是 \(\frac{n}{n-2i+1}\)

因此,总变化量是 \(O(n \ln n)\)

考虑用优先队列维护最值:

  • 考虑保证所有位置的 \(\max\) 单调不增,每次尝试更新堆顶,当堆顶不再变化时便可移动 \(m\)
  • 先从小到大枚举 \(m\),此时 \(i \le m\)\(\max\) 单调不增,每次加入 \(i = m\) 的值后尝试更新堆顶即可
  • 同理,从大到小枚举 \(m\),维护 \(i \ge m\)\(\max\)
  • 注意不要把 \(n = 2i-1\)\(i\) 加入堆,特判即可

时间复杂度 \(O(n \log n \log V)\)

10.23

P11675 [USACO25JAN] Photo Op G (set 维护连通块合并与所有答案)

注意到不能走的区域形成了许多四边形块

动态加入线段,维护每个四边形块的 \([x_1, x_2], [y_1, y_2]\)

同时,动态维护所有合法的斜线

合并连通块时,总连通块个数 \(-1\),合并次数是 \(O(n)\) 的,影响的斜线个数是 \(O(1)\)

注意起 / 终点为 \(X\) / \(Y\) 的斜线需要特殊维护

set 维护一切,时间复杂度 \(O(n \log n)\)

其实是细节太多了懒得详细写了

10.24

摆烂

10.26

模拟赛

10.26 T1 - 冬夜愚戏之歌 (组合数学 + 容斥 / 生成函数)

法 1:

\(a_i\) 能取负的很烦,考虑变成 \(a_i \in [0, 2k]\),要求 \(\sum\limits_{i=1}^{n} a_i \ge \text{lb}+nk\)

\(\sum\limits_{i=1}^{n} a_i = j\) 时,容斥去掉上界,方案数为 \(\sum\limits_{p=0}^{n} (-1)^p \binom{n}{p} \binom{j-2kp+n-1}{n-1}\)

总方案数为 \(\sum\limits_{p=0}^{n} (-1)^p \binom{n}{p} \sum\limits_{i=\text{lb}+nk}^{2nk} \binom{i-2kp+n-1}{n-1}\)

由公式 \(\sum\limits_{i=0}^{n} \binom{i}{k} = \binom{n+1}{k+1}\) (证明考虑补上 \(\binom{0}{k+1}\),由 \(\binom{n}{k} = \binom{n-1}{k-1} + \binom{n-1}{k}\) 滚雪球即可),后面的和式容易算

线性求逆元,预处理阶乘及其逆元求组合数,时间复杂度 \(O(Tnk)\)

法 2:

仍然先转化为 \(a_i \in [0, 2k]\)

考虑生成函数,设答案的生成函数为 \(F(x)\),多填一个数相当于乘上 \(G(x) = 1+x+x^2+\cdots+x^{2k}\)

\(F(x)\) 的初值为 \(1\),最终答案的生成函数即为 \(G^n(x)\)

\[\begin{aligned} G(x) &= \frac{1-x^{2k+1}}{1-x} \\ G^n(x) &= \frac{1}{(1-x)^n} \cdot (1-x^{2k+1})^n \\ \frac{1}{(1-x)^n} &= \sum_{i=0}^{\infty} \binom{n+i-1}{i} x^i \end{aligned} \]

用二项式定理暴力求 \((1-x^{2k+1})^n\) 即可,有值的位置只有 \(n\)

时间复杂度 \(O(Tnk)\)

10.26 T2 - 方格取数 (转化限制 + 高维前缀和)

\(m\) 为路径总数,直接暴力枚举相邻的折线可以做到 \(O(km^2)\)

考虑如何刻画 "相邻折线"

对一条折线,记其经过的第 \(i\) 列的最靠下的位置为 \(v_i\)

则折线 \(\{v'\}\) 在折线 \(\{v\}\) 下方等价于 \(\forall i,\ v'_i \ge v_i\)

注意到这实际上就是做 \(k-1\) 次高维前缀和

枚举 \(k\),令 \(f_{\{v\}}\) 表示选了前 \(k\) 条路径,最下方的路径为 \(\{v\}\) 的所有方案价值和

朴素转移为 \(f_{\{v\}} \leftarrow f_{\{v\}}+f_{\{v'\}}\ [\forall i,\ v_i \ge v'_i]\)

按照高维前缀和的思想,从高到低枚举每位 \(\text{bit}\) (从 \(1\) 开始),转移为:

  • \(f_{\{v_1, v_2, \cdots, v_{\text{bit}}, \cdots, v_{n}\}} \leftarrow f_{\{v_1, v_2, \cdots, v_{\text{bit}}, \cdots, v_{n}\}} + f_{\{v_1, v_2, \cdots, v_{\text{bit}}-1, \cdots, v_{n}\}}\ [v_{\text{bit}}-1 \ge v_{\text{bit}-1}]\)

  • 当然,这是错的

    以路径 \(\{1, 1, 3\}, \{1, 2, 3\}, \{1, 3, 3\}\) 为例,所有路径的权都是 \(1\)

    • 初始时,\(f_{\{1, 1, 3\}}, f_{\{1, 2, 3\}}, f_{\{1, 3, 3\}} = 1\)
    • 先进行转移 \(f_{\{1, 2, 3\}} \leftarrow f_{\{1, 2, 3\}}+f_{\{1, 1, 3\}}\),此时 \(f_{\{1, 2, 3\}} = 2\)
    • 再进行转移 \(f_{\{1, 3, 3\}} \leftarrow f_{\{1, 3, 3\}}+f_{\{1, 2, 3\}}\),此时 \(f_{\{1, 3, 3\}} = 3\)
    • 但是,\(f_{\{1, 3, 3\}}\) 应该为 \(4\),即 \(\{\{1, 1, 3\}, \{1, 3, 3\}\}, \{\{1, 2, 3\}, \{1, 3, 3\}\}\) 两种方案的价值和

    为什么错?容易发现,\(f_{\{1, 3, 3\}}\) 本来应该算 \(2\) (方案个数) 次,我们却只算了 \(1\)

    因此,令 \(f'_{\{v\}}\) 表示选了前 \(k\) 条路径,最下方的路径为 \(\{v\}\),暂不考虑 \(\{v\}\) 本身的贡献,所有方案的价值和

    再令 \(g_{\{v\}}\) 表示选了前 \(k\) 条路径,最下方的路径为 \(\{v\}\),总的方案数

  • 真正的转移为

    • 先从高到低枚举 \(\text{bit}\)

      \(f_{\{v_1, v_2, \cdots, v_{\text{bit}}, \cdots, v_{n}\}} \leftarrow f_{\{v_1, v_2, \cdots, v_{\text{bit}}, \cdots, v_{n}\}} + f_{\{v_1, v_2, \cdots, v_{\text{bit}}-1, \cdots, v_{n}\}}\ [v_{\text{bit}}-1 \ge v_{\text{bit}-1}]\)

      这里 \(f_{\{v\}}\) 维护的是选了前 \(k-1\) 条路径,最下方的路径为 \(\{v\}\),考虑了 \(\{v\}\) 的贡献,所有方案的价值和

      随着 \(\text{bit}\) 的改变,\(f_{\{v\}}\) 相当于 \(k-1\) 条路径的方案价值和的高维前缀和

      注意,\(k\) 条路径的方案价值和不是 \(f_{\{v\}}\)

      \(f'_{\{v_1, v_2, \cdots, v_{\text{bit}}, \cdots, v_{n}\}} \leftarrow f'_{\{v_1, v_2, \cdots, v_{\text{bit}}, \cdots, v_{n}\}} + f_{\{v_1, v_2, \cdots, v_{\text{bit}}-1, \cdots, v_{n}\}}\ [v_{\text{bit}}-1 \ge v_{\text{bit}-1}]\)

      这里 \(f'_{\{v\}}\) 维护的东西同上述定义

      这个转移的意义为在 \(f_{\{v'\}}\) 的基础上再拼上 \(\{v\}\),从 \(k-1\) 条路径变成 \(k\) 条;但 \(\{v\}\) 的贡献并不现在算

      由于 \(f_{\{v\}}\) 已经代表高维前缀和,无需从所有 \(\{v'\}\) 转移,从 \(\{v\}\) 的上一个转移即可

      \(g_{\{v_1, v_2, \cdots, v_{\text{bit}}, \cdots, v_{n}\}} \leftarrow g_{\{v_1, v_2, \cdots, v_{\text{bit}}, \cdots, v_{n}\}} + g_{\{v_1, v_2, \cdots, v_{\text{bit}}-1, \cdots, v_{n}\}}\ [v_{\text{bit}}-1 \ge v_{\text{bit}-1}]\)

      这里 \(g_{\{v\}}\) 其实同时维护了高维前缀和 / 当前 \(k\) 条路径的方案数

      按维护 \(f_{\{v\}}\) 的方式写成 \(g_{\{v\}}\)\(g'_{\{v\}}\) 当然没问题,不过这里没有 \(\{v\}\) 需要重复贡献的问题,可以合并

    • 枚举完 \(\text{bit}\) 后:

      \(g_{\{v\}} \leftarrow g_{\{v\}} - \text{tmp}_{\{v\}}\)\(\text{tmp}_{\{v\}}\) 表示选 \(k-1\) 条路径时 \(g_{\{v\}}\) 的值

      注意到 \(g_{\{v\}}\) 的转移中其实多考虑了从 \(k-1\) 条路径时的 \(g_{\{v\}}\) 转移来的贡献

      换句话说,我们多算了上一条是 \(\{v\}\),这一条还选 \(\{v\}\) 的贡献,这其实是不合法的

      因此减去即可

      \(f_{\{v\}} \leftarrow f'_{\{v\}} + g_{\{v\}} \cdot w_{\{v\}}\)\(w_{\{v\}}\) 代表路径 \(\{v\}\) 的价值和

      这个转移表示加上之前暂时没有考虑的 \(\{v\}\) 的贡献

  • 初始值为:

    • 全局初始值为 \(f_{\{v\}} = w_{\{v\}},\ g_{\{v\}} = 1\)
    • 在每次 \(k \rightarrow k+1\),枚举 \(\text{bit}\) 前,将 \(f'_{\{v\}}\) 清零
  • 答案为 \(k! \cdot \sum\limits_{\{v\}} f_{\{v\}}\)

  • 实现细节上:

    • 可以对 \(\{v\}\) 进行 hash,预处理某一位减 \(1\) 后的 \(\{v'\}\) 的编号

    • 需要按照 \(v_{\text{bit}}\) 从小到大对 \(\{v\}\) 排序,这样高维前缀和才是对的

    • 我们假装没有不合法的路径

      换句话说,我们仍枚举每个不合法路径并转移

      对不合法路径,视其初始值为 \(f_{\{v\}}, g_{\{v\}} = 0\),最终仍为 \(0\)

      这样逐位 \(-1\) 转移才是对的

时间复杂度 \(O(knm)\)

10.26 T3 - 这是我新买的象棋波特 (观察性质 + 贪心)

考虑枚举答案所在列 \(i\)

容易发现,若最优方案中离 \(i\) 更远列能合并到 \(i\) 上而更近列不能,必能调整使得更近列合并到 \(i\)

因此,会有一段前缀 \([l_i, i-1]\) 与一段后缀 \([i+1, r_i]\) 合并到 \(i\)

考虑贪心,从前向后扫,每次优先让最低的棋子移到下一列,维护前缀合并的最优方案;后缀同理

由于叠棋子的总数是 \(O(m)\) 的,时空复杂度没有问题

合并 \(i-1, i+1\) 时,将所有棋子从低到高排序,按相同策略合并即可

可以双指针维护,时间复杂度 \(O(m \log m + n)\)

10.26 T4 - 偶数题 (转化限制 - 赋势能 + 树形 DP)

首先容易观察出 type 为 \(0\) 时答案为 \(D\),其中 \(D\) 为直径长度的一半

证明考虑以直径中点为根,按深度奇偶赋值即可

这启示我们以直径中点为根考虑;记 \(\text{dep}_i\) 为点 \(i\) 到根经过的边数,\(\text{dis}_{i, j}\) 为点 \(i, j\) 间简单路径的边数

考虑给每个点赋势能 \(h_i\) 以刻画 \(f(P)\)

注意到 \(P\) 中边数确定,若知道两种方向的边的数量之差,就能算出 \(f(P)\)

因此,我们要求对定出的有向边 \(u \rightarrow v\),满足 \(h_v = h_u - 1\)

因此有 \(\displaystyle f(P) = \frac{\text{dis}_{u, v}+|h_u-h_v|}{2}\),其中 \(u, v\) 为路径两端点

注意到对所有可能成为直径两端点的点 \(u, v\),有 \(h_u - h_v = 0\);因此令所有 \(\text{dep}_u = D\) 的点 \(u\) 的势能为 \(0\)

限制转化为 \(\forall u, v,\ |h_u-h_v| \le 2D-\text{dis}_{u, v}\)

考虑将 \((u, v)\) 的限制转化为 \(u, v\) 各自的限制;因此,我们希望对每个点考察其最严的限制

感性理解上,路径越长,限制越严;可以猜测 \(\text{dep}_v = D\) 时限制最严,为 \(|h_u| \le D-\text{dep}_v\)

证明充分性:\(|h_u-h_v| \le |h_u|+|h_v| \le (D-\text{dep}_u)+(D-\text{dep}_v) \le 2D-\text{dis}_{u, v}\)

因此,只需满足:

  • \(\text{dep}_u = D\) 时,令 \(h_u = 0\)
  • 对边 \((u, v)\),有 \(|h_u-h_v| = 1\)
  • 对点 \(u\),有 \(|h_u| \le D-\text{dep}_u\)

\(f_{u, w}\) 表示考虑 \(u\) 子树,\(h_u = w\) 的方案数,对 \(h_u\) 树形 DP 即可

时间复杂度 \(O(n^2)\)

posted @ 2025-10-06 13:36  lzlqwq  阅读(2)  评论(0)    收藏  举报