[Record] 杂题选做-NOIP
感觉很多题过了就跑了,理解得很不够……不能再颓了!
WD 是 Worth Doing
P7718 「EZEC-10」Equalization
将区间加法转换到差分序列 \(\{d_i\mid d_i=a_{i+1}-a_{i}\}_{i=0}^{n}\) 上,在原序列 \([l_i,r_i]\) 加 \(v_i\),等价于在差分序列上在 \(l_i\) 加 \(v_i\),在 \(r_i\) 减 \(v_i\),这时考虑将 \((l_i, r_i+1)\) 连边。
可以发现问题的目标是将 \(d_{1\sim n-1}\) 这些点消为 \(0\)。
现不考虑 \(0,n\) 两个点,在 \(1\sim n-1\) 这些点内部连边进行加减操作。
(不)容易发现,对于下标集合 \(S\),若 \(S\) 内所有 \(d_i\) 求和等于 \(0\),则可以通过 \(|S|-1\) 次操作将 \(S\) 内所有元素的 \(d_i\) 消为 \(0\),且此时的连边情况为一棵树。根据 Cayley 定理,方案数量为 \(|S|^{|S|-2}\)。若 \(S\) 内所有 \(d_i\) 求和不为 \(0\),则需要 \(|S|\) 次才能消去。
因此设 \(f_{S,i}\) 表示当前选择的元素构成集合 \(S\),集合 \(S\) 中组成了若干 \(\sum b_i=0\) 的块,剩下尚未组成块的元素有 \(i\) 个,此时的 \(\{\)块数量的最大值\(,\)对应方案数\(\}\),记为 \(\{mx, cnt\}\)。
一般地,在 \(S\) 中加入元素 \(x\)(\(x\not\in S\)),转移为:
如果 \(sum[S]=0\),则尚未组成块的 \(i\) 个元素可以组成块,转移为:
考虑最后统计答案,此时枚举一个集合 \(S\),集合 \(S\) 内的元素可以在 \(1\sim n-1\) 内部连边消为 \(0\),其余元素需要向 \(0\) 或 \(n\) 连边,令 \(0,n\) 联通,根据广义 Cayley 定理,方案数量为 \(2(|U|-|S|+2)^{|U|-|S|-1}\)。
也就是:
注意在 \(dp\) 中,集合之间有序,而操作之间无序,因此最终答案式子还需做消序和定序,也即:
P10197 [USACO24FEB] Minimum Sum of Maximums P
首先对 \(\max\) 进行简单转换:\(\max(a,b)=\dfrac{a+b+|a-b|}{2}\)。
只用考虑最小化绝对值之和。
在 \(0,n+1\) 位置引入两个极大值且规定它们在 \(x\) 序列中,可以发现共有 \(k+2\) 个不动点,将序列划分为 \(k+1\) 段。
通过调整法可以证明以下结论成立:
- 每一段为一个单调不增或单调不减的连续子序列。
- 每一段的值域区间两两相离或相含,不可能相交。
因此可以考虑对值域进行区间 dp,对段进行状压。具体地,设 \(f_{l,r,S}\) 表示使用了值域区间 \([w_l,w_r]\),已被完全填充的段的集合为 \(S\) 时,绝对值之和的最小值。
每一段内部单调,因此贡献可以视作只与左右端点相关,设 \(L_i,R_i\) 分别为段两端的不动点,其中 \(L_i\) 为值较小者,\(R_i\) 为值较大者,一段的贡献为:
一般的情况是填入一个数,可以视作不产生贡献。
考虑两个段的值域区间相离的情况,设 \(sum_S\) 为集合 \(S\) 中所有段的长度总和,则在 \(sum_S \leq r-l+1\) 时,有转移:
相含的情况可以在某段被完全填充时合并考虑,在 \(sum_S=r-l+1\) 时,枚举当前填充段 \(i\)(\(i\in S\)),有转移:
特别地,在 \(l=r\) 时,\(f_{l,r,S}\leftarrow w_{i,l,r}\)。
P13866 [SWERC 2020] Daisy's Mazes [WD]
很有趣的一道题。
比较傻地对栈序列 dp,显然状态数量是 NP 的。考虑如何减少状态。
假设一种简单情形,也即在出发点和结束点栈都为空,可以看作走了一条合法括号路径,那么可以根据实现的精细程度有各种各样的多项式复杂度算法判断是否存在这样一条路径。具体而言将转移分为括号序列拼接(传递闭包)和在括号序列外层增加一层括号两种,记忆化搜索即可。
这启发我们可以通过添加虚点将初始栈序列和结束栈序列不为空时的栈序列状态转换为虚点之间的路径(换而言之,将状态转换到自动机上),使问题归为前面简单的判定问题。
具体地,对于起始状态,增加 \(n\sim 2n-1\) 号节点,对于 \(n<i\leq 2n-1\),向 \(i-1\) 号节点连所有 \(k\) 中颜色的边,\(n\) 号节点向 \(0\) 号节点连所有 \(k\) 中颜色的边。对于终止状态,\(n-1\) 号节点向自己连所有 \(k\) 种颜色的边。
P8868 [NOIP2022] 比赛
洛谷的题解写的推式子的方式看起来很学不会,固定自己的套路,历史版本和使用线性函数形式进行推导。
- 诚然可以列出 \(5\times 5\) 的矩阵,接下来要么神通广大地卡常,要么精力旺盛地拆分 \(125\) 个转移手算去掉无效转移合并相同转移。
- 诚然也可以直接写分块,免去线段树下传标记讨论的麻烦,接下来充分发扬 \(\text{Ynoi}\) 的精神。
先注意一个问题,虽然有最值修改依据值域连续段转覆盖为加法的套路,但查询的东西是历史版本和,没有必要将区间覆盖标记转化为加标记,这样会更麻烦。
设出答案:
将 \(\max a\) 和 \(\max b\) 分别记作 \(X_l\) 和 \(Y_l\),答案可以表示为一个函数的形式,也即:
懒标记也便顺势维护 \(k_{x,y},k_{x},k_{y},C\) 几个系数项,其合并也即计算复合函数。
P9531 [JOIST 2022] 复兴计划 / Reconstruction Project
所有点可以联通的最小价值,显然考虑 MST。观察到 \(n\) 远小于 \(m,q\),考虑尽量优化到与 \(n\) 相关。
暴力的 \(O(qm\log m)\) 是没有什么价值的,考虑一个更加优雅的暴力:对于当前的需求 \(X\),将边分为 \(W_i\leq X\) 和 \(W_i>X\) 两种,则以 \(|X-W_i|\) 为边权的最小生成树上的边一定来源于第一种边构成的最大生成树和第二种边构成的的最小生成树。
这样可以做到 \(O(n(m+q))\)。
对上边的算法的式子做一定的转换,找到每条边的贡献区间。考虑前缀生成树,按 \(|X-W_i|\) 从大到小加边,在 \(W_j\) 替换掉 \(W_i\) 时说明 \(X-W_i>W_j-X\),即在 \(X>\dfrac{W_i+W_j}{2}\) 时 \(j\) 开始产生贡献,同时 \(i\) 结束贡献。
随后分讨贡献区间为 \([L_i,R_i]\) 的某条边的贡献情况:
- \(X\in[L_i,W_i]\),贡献为 \(W_i-X\)。
- \(X\in(W_i,R_i]\),贡献为 \(X-W_i\)。
- \(X\in (-\infty,L_i)\cap(R_i,+\infty)\),贡献为 \(0\)。
差分计算一下贡献即可。
P3590 [POI 2015 R2] 三座塔 Three towers
有很正常的思路,但是官方是个神秘结论:答案的左端点在 \([1,3]\) 与右端点在 \([n-2,n]\) 两者必满足其一。
容易通过 \(O(n^2)\) 打表发现,容易通过反证法证明。
P7116 [NOIP2020] 微信步数
很幽默地发现本来写在代码注释里的题解被保存成了 UTF-8 编码。
题目要求 \(\sum_{\{i_1,i_2,\dots,i_k\}}f(i_1,i_2,\dots,i_k)\),其中 \(f\) 函数是一个点移出平面的时刻,一个基本的思路是交换求和顺序,枚举时刻,求解在该时刻有多少点被移出平面。
另一个基本思路是,对于多维问题,考虑将维度拆开,处理一维问题。
Lemma 0: 第 \(i\) 维度上不会走出边界的坐标构成连续区间 \([L_i,R_i]\)。
- 规定:\(x_i\) 为第 \(i\) 维度在执行一周期操作后的位移。
Lemma 1(Infinite 判定): 答案为 \(+\infty\) 当且仅当存在某出发点在第一周期操作内不会走出平面且 \(\forall i,x_i=0\)。
Lemma 2(「特殊」操作的定义): 只有位移构成正方向或负方向的前缀最值的操作可能对答案产生贡献,称这种操作为 「特殊」 的。
考虑第 \(i\) 次操作对答案的贡献,显然有:
Lemma 3(「特殊」操作的周期性质): 去除第一周期具有独立性,从第二周期开始,所有周期的「特殊」操作分布完全相同。
Lemma 3 提示了可能可以暴力处理掉第一周期,对于剩下的周期进行统一处理。
假设第 \(n+i\) 次(\(1\le i\le n\))操作是「特殊」的,考虑其在第 \(t\) 周期 (\(t\ge2\))的贡献:
可以发现式子为关于 \(t\) 的 \(k\) 次多项式,因此可以对于每个 \(i\) 算出 \(F_i\) 的各项系数,由于 \(k\) 很小,可以暴力进行多项式乘法,这一步的复杂度是 \(O(nk^2)\) 的。
设第二周期内的第 \(i\) 次操作最多执行的轮数为 \(T\),有:
考虑第二周期第 \(i\) 次操作的贡献:
这样就转换成了自然数幂和的形式,使用 Lagrange 插值或第二类 Stirling 数解决均可。
AT_codefestival_2016_final_h Tokaido
很好的题目。
如果 Alice 先跳到 \(i\),则 Bob 先取完 \(i\) 之前的点的价值再往后跳一定是最优的。原因是跳这些点时不会影响 Bob 和 Alice 的位置关系,始终由 Bob 进行下一次操作。
Bob 一定会走到 \(i-1\),此时得到一个 Alice 和 Bob 先后手顺序交换后的子问题。
设 \(f_i\) 为 Alice 和 Bob 初始位置分别为 \(i-1,i\) ,此时开始博弈的答案,有转移:
最终答案为 \(a_1+f_2\)。
设 \(s=\sum_{j\le i}a_j\),则转移式子可以写成:
使用后缀最值优化一下容易做到 \(O(nm)\)。
考虑优化,观察到若 \(s_{n-1}<a_n\),则 Alice 必须第一步就跳过去,否则会使 Bob 取到 \(s_{n-1}\),这样答案就会变成负数,因此只用处理 \(a_{n}\le s_{n-1}\) 的 \(a_n\),时间复杂度优化为 \(O(n\sum_{i=1}^{n-1}a_i+m)\)。
设 \(g_i=\min_{j\ge i}\{f_j+s_{j-1}\}\),也即后缀最值优化的数组,代入 \(f_i\) 的转移式,有:
这也就是说,给定一个初始值 \(g_0=s_{n-1}-a_n\),依次经过 \(i=n-1,n-2,\dots,3\),每次执行操作:
- 若 \(g_0>s_{i-1},g_0\leftarrow 2s_{i-1}-g_i\)
求解最终 \(g_0\) 的结果。
注意到 \(s_i\) 有单调性且操作完成后 \(g_i<s_{i-1}\),所以记 \(h_i\) 表示 \(g_0\) 初始值为 \(i\) 的最终 \(g_0\) 值,可以得到递推式:
预处理 \(i=1,2,\dots,\sum_{i=1}^{n-1}a_i\) 的 \(h_i\),容易通过双指针计算。
时间复杂度 \(O(\sum_{i=1}^{n-1}a_i+m)\)。
AT_agc045_e [AGC045E] Fragile Balls
首先可以很简单地找到一种无解的情况:
- \(\exists u,in_u=0\text{ and }out_u>0\),此时 \(u\) 中的人走到所有出边指向的点后,这个点处于无人值守的状态,显然不合法。
判掉以上的无解情况。
考虑 \(c_i=1\) 的情况,可以发现 \(u\) 能走到 \(v\) 当且仅当 \(u\) 已被某个点的出边走到过或 \(out_u>1\)。显然,条件中的前者是一种拓扑依赖关系,而条件中的后者是不需要借助其他点的,我们将存在 \(out_u>1\) 的连通块称为「特殊」的。
下发的题解定义「特殊」连通块为「强连通分量」,他开心就好。
则有解的条件为对于所有连通块,均满足连通块大小为 \(1\) 或其为「特殊」的。具体的构造是先让 \(out_u>1\) 的 \(u\) 走到对应的若干个点,然后这些点中的人被释放出来,走到其他点,如此可以走完连通块中的所有边。
在 \(c_i>1\) 时,一些点可以绕远路去走其他连通块内的点,使该连通块某个点被释放出来,称这种操作为「帮助」,设 \(k\) 为非「特殊」非孤立点连通块的数量,总计需要 \(k\) 次「帮助」。
可以发现答案至少为 \(k+\sum[A_i\not=B_i]\),考虑额外的代价。
此时可以将题目中的边分类,考虑它们对「帮助」的需求(代价)和它可以进行「帮助」的点的数量(贡献)。
- A 非自环边:
- A1 处于「特殊」连通块中:代价为 \(0\),贡献为 \(c_i-1\)。
- A2 处于非「特殊」连通块中:代价为 \(1\),贡献为 \(c_i-1\)。
- B 自环边:
- B1 处于「特殊」连通块中:代价为 \(1\),贡献为 \(c_i-1\)。
- B2 处于非「特殊」连通块中(孤立点):代价为 \(2\),贡献为 \(c_i-2\)。
注意 A2 类型的代价总和被提前计算成了 \(k\),因此可以视作 A1、A2 均是代价为 \(0\) 的边。
可以发现,A1、B1 可以随时使用,不依赖于出发点所处连通块是否已被「帮助」;而 A2、B2 必须在被「帮助」后才能被释放出来进行使用。
那么如果存在 A1 类型的边,则所有边均可依靠某种拓扑顺序被释放出来;否则需要先使用一个 B1 类型的边释放其他边。如果两者都不存在,则无解。
随后使用掉所有 A1、A2 边,将 B1、B2 分别按贡献从大到小排序,枚举 B1、B2 分别产生的贡献,计算最小代价即可。
P10202 [湖北省选模拟 2024] 沉玉谷 / jade
每次删除一个区间,结合数据范围,考虑区间 dp。
区间 dp 的一种常见视角是将每次操作区间按照包含关系建成树形结构,考虑已经确定这种树形结构的情况下,操作顺序的数量即为树的拓扑序计数,即 \(\dfrac{n!}{\prod sz_i}\)。
回到区间视角,\(sz_i\) 也即操作次数,由上面的式子,可以发现它是必须记入状态的。
设 \(f_{l,r,k}\) 为区间 \([l,r]\) 删 \(k\) 次删空的方案数量,但这个状态是不好转移的,套路性地,考虑最后一次删除,设 \(g_{l,r,k,x}\) 为区间 \([l,r]\) 删 \(k\) 次后只剩下颜色 \(x\) 的方案数量,且这些点将在接下来被一次性全部删除。
对于 \(g\) 的转移,考虑枚举区间 \([l,r]\) 内颜色为 \(x\) 且未被删除的第一个点 \(p\),有转移:
\(f\) 直接使用 \(g\) 转移:
时间复杂度 \(O(n^5)\)。
P6377 [PA 2010] Termites
记答案分别为 \(ans_1,ans_2\),令 \(rst=ans_1-ans_2\),考虑求解 \(rst\) 的值。
按照 0 分段,将整个序列划分为若干个双端队列,特殊地,开头结尾的连续段构成栈,可以进行形如 结尾+-INF+开头 这样的拼接,将这两个栈拼成一个双端队列。
考虑一种特殊情况,如果一个双端队列是单谷的,则对其进行选择的最优策略是取左右两端中的较大元素,这是很容易证明的。
如果一个双端队列不是单谷,则需要通过某种方式转换为一个单谷的形式,考虑存在破坏单谷的结构 \(a_{i-1}\le a_i\text{ and }a_i\ge a_{i+1}\),我们声称将其替换为 \(a_{i-1}+a_{i+1}-a_{i}\) 对于 \(rst\) 的值的计算是完全等效的。
直接模拟双方决策容易证明以上的结论。
使用优先队列维护贪心决策即可。
P12073 [OOI 2025] Alice, Bob, and two arrays. [WD]
时间复杂度中,规定 \(N\) 与 \(M\) 同阶,\(n\) 与 \(m\) 同阶。
Subtask 1 (13 pts)
将二元组 \((l_i,v_i)\) 展开,还原成 \(a,b\) 序列,考虑建立两个序列的子序列自动机。
设 \(f_{i,j}\) 为从 \((i,j)\) 出发决策(不能选择 \((i,j)\))的先手必胜必败状态,\(i,j\) 从大往小枚举。转移时每次枚举添加的字符 \(c\),根据子序列自动机找到添加 \(c\) 后在 \(a,b\) 中跳到的位置,对于后继状态,若存在必败态,则 \(f_{i,j}\) 必胜,否则 \(f_{i,j}\) 必败。
时间复杂度 \(O(N^2k+q)\)。
Subtask 2 (25 pts)
考虑刚刚的转移,注意到如果 \(i\) 不变,\(j'\leftarrow j-1\),则此时位置 \((i,j')\) 只有添加字符 \(b_j\) 这一后继状态与 \((i,j)\) 不同,其余后继状态可以完全继承。
因此另设 \(g_{i,j}\) 表示 \((i,j)\) 添加不等于 \(b_j\) 的字符可以转移到的后继必败状态数量,辅助 \(f\) 的转移。
时间复杂度 \(O(N^2+q)\)。
Subtask 3 (83 pts)
回到字符连续段上考虑,可以发现对于 \(a,b\) 的字符连续段组 \((x,y)\),且两个字符连续段中的字符类型一致,设为 \(t\),则除了 \(t\) 以外的字符的后继位置都在 \(x,y\) 两段之外,对于每一个位置都去转移是没有意义的,只用转移每段开头的字符。这个过程的可以使用与 Subtask 2 一致的优化,使得时间复杂度降为 \(O(nm)\)。
如果进行除 \(t\) 以外的转移没有找到必败态,则只能通过 \(t\) 转移,游戏双方的最优策略均为轮流填 \(t\),直至转移出当前状态。暴力向后跳,设当前位置为 \(p_1,p_2\),每次去除 \(\text{LCP}(a[p_1:n],b[p_2:m])\),当前连续段被跳完时,跳到子序列自动机的后继状态。
时间复杂度 \(O(n^3+nq)\)。
Subtask 4 (100 pts)
Subtask 3 的时间复杂度在于暴力跳 \(t\) 的过程,因此考虑对每一个 \(t\) 维护一个数据结构。不难发现,若当前下标位置对为 \((x,y)\),则当 \(x-y\) 为定值时,答案仅与 \(x\) 的奇偶性有关。
于是可以使用 ODT 维护这个东西。
P14372 [JOISC 2018] 比太郎的聚会 / Bitaro's Party
每次询问给定若干关键点,考虑集合和平衡规划,设阈值为 \(B\),分别考虑每次询问集合 \(S\) 小于或大于等于 \(B\) 的情况。
后者是很好处理的,这样的询问总共不会超过 \(O(\dfrac{\sum Y}{B})\) 个,直接暴力 dp 求解 DAG 最长链。
对于前者,考虑对每个终点预处理到达它的距离前 \(B\) 大的点集,按照拓扑序归并即可。
CF1452G Game On Tree
简单题。
容易想到,Alice 的最优策略是走树上的一条简单路径到达某个点,然后在那个点苟到 Bob 走过来。这是因为最后 Alice 苟着的节点一定要求是它能到达的节点中 Bob 到达时间最晚的,那么在路上打转的过程中 Bob 可能可以切断某些路径,使得 Alice 无法到达最优节点。
考虑什么样的点可以被 Alice 到达,由某出发点 \(s\) 能到达点 \(t\) 仅当路径上所有节点 Bob 都不能在 Alice 到达前到达,设 \(d_i\) 为 \(i\) 到最近关键点的距离,也即 \(\forall i\in \text{Path}(s,t), d_i>\text{dis}(s,i)\)。
路径上所有点均满足条件是很不好做的,但很快便可以发现,以上式子与 \(d_t>\text{dis}(s,t)\) 是完全等价的。
考虑反证法:将以上式子移项为 \(d_i-\text{dis}(s,t)>0\),如果路径上存在点 \(i\) 对路径可达性的限制强于 \(t\),则有 \(d_i-\text{dis}(s,i)<d_t-\text{dis}(s,t)\),则 \(\text{dis}(s,t)-\text{dis}(s,i)<d_t-d_i\),也即 \(\text{dis}(i,t)+d_i<d_t\),这与 \(d_t\) 是到关键点的最短距离产生矛盾。
因此每个点 \(i\) 可以对其 \(d_i-1\) 级邻域的答案产生贡献,使用点分治,时间复杂度 \(O(n\log^2 n)\)。
实现精细一些应该能做到单 \(\log\)。
P12448 [COTS 2025] 观草 / Trava
场切。放在 T2 是合适的,因为它确实比去年 T4 简单。
对于所有长度为 \(k\) 的区间长度求和是相当不好做的,但 \(a_k\leftarrow a_k+1\) 的修改操作给了很强的提示,这也就是说,如果对值域做扫描线,因为修改操作只在相邻两个版本之间产生影响,修改操作是没有后效性的。
还是值域压缩的套路:
存在量词的命题依然不好做,考虑取否命题改为全称量词。
将 \(>x\) 的数设为 1,否则设为 0,则以上式子只需要知道全零的极长连续段个数和极长全零连续段长度之和。
值域从大到小进行扫描线维护这些信息,对于每个全零连续段的加入删除,若其操作序列中的时刻编号为 \(t\),则这些修改对 \([t+1,q]\) 区间内的所有查询操作有贡献。
P11110 [ROI 2023] 陶陶装苹果 (Day 2) [WD]
相当本土化的翻译。
将 \(w_i\) 从小到大排序,维护 \(s_i=\sum_{j\leq i} w_i\)。
将合法点对 \((x,y)\) 放到平面上形成一块有色图形,每次查询 \((a,b)\) 要求其左下角的矩形内的点全部有色。
考虑逐个加入 \(w_i\),则图形要么向 \(x\) 轴正方向移动 \(w_i\) 个单位长度,要么向 \(y\) 轴正方向移动,要么不移动,将这三个面积取并集。
在依然可能存在新的合法查询点的情况下,归纳可以证明图形大致是等腰三角形,中间可能存在镂空部分,其中有效的镂空部分一定以 \(y=x\) 中轴线,且在 \(w_i>(s_{i-1}+1)/2\) 时产生,可以发现满足条件的 \(w_i\) 至多达到以 \(\frac{3}{2}\) 为底的值域 \(\log\) 的数量级。每次查询时暴力遍历这些镂空部分,看它们是否会影响到查询部分的合法性即可。
不用二分到对查询点限制最强的镂空部分,尽管大家都这么写,然而我的暴力遍历才是最快解。
CF2041N Railway Construction
一道非常难写的题。
首先不考虑删点,考虑如何 \(O(n+m)\) 地求出 ban 掉若干条边后的完全图的最小生成树。
并不容易发现,做一轮 Boruvka,也即将每个点连到它能够连到的点权最小的点,形成的连通块数量一定不超过 \(O(\sqrt{m})\),且每个连通块内部的最小生成树边一定是整个图的最小生成树边。
给出结论后这件事情是很容易证明的。
因此只用考虑合并这 \(O(\sqrt{m})\) 个连通块,继续使用 Boruvka 或者使用 Kruskal 的时间复杂度都会带一个 \(\log\),但考虑到这 \(O(\sqrt{n})\) 个连通块之间的合并可以视作完全图最短路,使用不加堆优化的 Prim 可以做到 \(O((\sqrt{m})^2)=O(m)\)。
然后考虑如何处理删点的情况。
另一个并不容易发现的事实是,原图按照以上方法求出的最小生成树非叶子节点的数量不超过 \(O(\sqrt{m})\) 个。
如此,叶子节点可以直接 \(O(1)\) 删除,对于非叶子节点,可以直接重构整张图,进行刚才的 Boruvka + Prim 的求解过程。
时间复杂度 \(O((n+m)\sqrt{m})\)。
P5982 [PA 2019] Trzy kule [WD] [Classic]
并不方便 dp,考虑组合计数。
发现本质不同的位置视对三个串产生贡献不同只有四种类型:
- 可以对 \(s_1,s_2,s_3\) 同时产生贡献或不产生贡献,记数量为 \(c_0\),其中 \(k_0\) 个产生贡献。
- 可以对 \(s_1,s_2\) 同时产生贡献或单独对 \(s_3\) 产生贡献,记数量为 \(c_1\),其中 \(k_1\) 个对前者产生贡献。
- 可以对 \(s_1,s_3\) 同时产生贡献或单独对 \(s_2\) 产生贡献,记数量为 \(c_2\),其中 \(k_2\) 个对前者产生贡献。
- 可以对 \(s_2,s_3\) 同时产生贡献或单独对 \(s_1\) 产生贡献,记数量为 \(c_3\),其中 \(k_3\) 个对前者产生贡献。
存在量词不好做,依然正难则反,考虑否命题转换为全称量词,列方程有:
考虑定二求二,枚举 \(k_0,k_1\),有:
使用二维前缀和即可维护。
P8175 [CEOI 2021] Tortoise
最多紫的一道黑。
两个人博弈是相当不好做的,但答案完全可以视作只与 Tom 的决策相关,因此考虑通过转换条件去掉 Wilco 这个人。
可以发现 Tom 的速度为 Wilco 两倍可以完全等价地看作其在相同时间内走过的路程是 Wilco 的两倍,因此如果 Tom 要取走位于点 \(i\) 的商店中的糖果,则在此前他走过的距离一定小于 \(2i\),这样 Wilco 这个人就成功地从游戏中被去除了。
很显然 Tom 一定是从前往后取走商店中的糖果(去往空地的路上可能折返,但这不重要),这给从前往后地贪心决策提供了条件。
发现 Tom 拿到一块糖后会有两种可能的决策:
- 找到离他最近的空地去把糖丢掉,再折返回来继续操作当前商店或往前走。
- 找到他下一个商店 \(x\) 和它后面的一块空地 \(y\),走到 \(y\) 丢掉糖,走到 \(x\),不再继续操作当前商店。
因为代价有上限,很显然使用反悔贪心维护。
P14382 [JOISC 2017] 开荒者 / Cultivation [WD]
这道题会写很细,因为我是个没脑子的傻缺。
首先给出最基本的一个性质。
Lemma 0:被覆盖的点的集合只与向四个方向移动的操作数量有关,与执行操作的先后顺序无关。
Explanation:设四个方向的移动操作数分别为 \(L,R,U,D\),一个单点 \((S_i,E_i)\) 以任意顺序进行所有操作后均会拓展成左上角为 \((S_i-U,E_i-L)\) 右下角为 \((S_i+D,E_i+R)\) 的矩形。
因此有了 Subtask 1~2 的做法:
- Subtask 1~2:枚举四个方向移动的操作数量 \(L,R,U,D\),判断矩形是否被完全覆盖即可,时间复杂度 \(O(R^2C^2N)\)。
继续考虑,存在 \(L,R,U,D\) 是一件相当麻烦的事情,因此考虑定二求二,枚举 \(U,D\),考虑计算此时能覆盖整个矩形的 \(L,R\)。
首先执行 \(U\) 次向上和 \(D\) 次向下的移动,标记出当前被覆盖的点,复杂度 \(O(NR)\)。
考虑只有一行的情况,此时找到所有标记点,设第一个标记点到左边界的距离为 \(x_i-1=a\),设最后一个标记点到右边界的距离为 \(R-x_k=b\),相邻标记点之间距离最大值 \(\max_{i=1}^{k-1}(x_{i+1}-x_i-1)=c\)。此时有 \(L\geq a,R\geq b,L+R\geq c\)。
如果有多行也是同理的,对所有 \(a,b,c\) 取最值即可,也即 \(L\geq\max_{i=1}^{R}a_i,R\geq\max_{i=1}^{R}b_i,L+R\geq\max_{i=1}^{R}c_i\)。
因此 \(L+R\) 最优取到 \(\max\{\max_{i=1}^{R}a_i+\max_{i=1}^{R}b_i, \max_{i=1}^{R}c_i\}\),这个东西的计算是 \(O(N)\) 的。
因此有 Subtask 3 的做法:
- Subtask 3:枚举上下两个方向移动的总量 \(U,D\),求解 \(L+R\),时间复杂度 \(O(NR^3)\)。
可以发现这个算法是相当有启发意义的,但复杂度中带 \(R\) 非常不优,考虑如何向点数转化。显然,我们需要去除一些完全等效的 \(U,D\)。
Lemma 1:取 \(U\in\{S_1-1,S_2-1,\dots,S_N-1\}\),\(D\in\{S_i-S_j-1\mid S_i > S_j\}\cup\{R-S_i\}\),即可遍历所有可能成为最优的移动情况。
Explanation:首先,移动只可能使得某一列上某两个关键点 \(i,j\) 之间的所有空白点(或到达左右边界)均被恰好填充,否则通过调整法可以证明不优。其次,对于某一列上两个原有的相邻关键点 \(i,j\) 之间的空白行,它们可以视作是完全相同的,因而本质不同的被填充的状态仅取决于填充的总列数,也即 \(U+D\),\(U,D\) 的具体值只是使得未被填充的行发生纵向的平移,因此可以直接钦定 \(D\) 负责这些贡献。
所以 \(R^2\) 的枚举可以由枚举关键点等效替代为 \(N^3\) 个状态,可以得到 Subtask 4 的做法。
- Subtask 4:枚举可能成为最优答案的 \(O(N^3)\) 组 \(U,D\),求解 \(L+R\),时间复杂度 \(O(N^5)\)。
Subtask 5 可以考虑优化 Subtask 4 的复杂度瓶颈,也即暴力标记出在操作 \(U,D\) 后被覆盖的点,也可以继续考虑性质。
同时枚举 \(L,R\) 是非常难以继续的,可以发现刚刚 Lemma 1 的 Explanation 中提出,两个同列相邻关键点 \(i,j\) 之间的空白行本质不同状态只取决于 \(U+D\),那为什么不直接枚举 \(U+D\) 呢?
那么考虑可能产生贡献的 \(U+D\) 有哪些。
Lemma 2:取 \(U+D\in\{S_i-S_j-1\mid S_i>S_j\}\cup\{S_i-S_j+R-1\mid S_i-S_j<R\}\),即可遍历所有可能成为最优的移动情况。
Explanation:对 Lemma 1 稍加扩展即可。
得到 Subtask 5 的做法:
- Subtask 5:枚举可能成为最优答案的 \(O(N^2)\) 种 \(U+D\),求解 \(L+R\),时间复杂度 \(O(N^4)\)。
钦定每个原有点标记了上方的 \(U+D\) 个点,维护所有行的关键点间隔,这件事是可以通过一个滑窗的形式解决的。具体地,滑窗维护上下边界 \([i,p]\),满足 \(S_i-1+R-S_p\leq U+D\)。接下来可以分别使用三个单调队列优化维护前文中的 \(\max_{i=1}^{R}a_i,\max_{i=1}^{R}b_i,\max_{i=1}^{R}c_i\) 可以优化到 \(O(N^3)\)。
实现上可以考虑一件事情:将 \(S_i\) 从小到大排序,枚举 \(U+D\) 时,有效的 \(U+D\) 必然满足 \(U+D\geq \max_{i=1}^{N-1}{S_{i+1}-S_i-1}\) 且 \(U+D\geq\max\{S_1-1,R-S_N\}\)$。对满足这种特殊性质情况画图后可以发现似乎并不需要使用单调队列。
- Subtask 6:滑窗优化 Subtask 5 中对 \(\max_{i=1}^{R}a_i,\max_{i=1}^{R}b_i,\max_{i=1}^{R}c_i\) 的维护。
P6844 [CEOI 2019] Building Skyscrapers
场切一半?毕竟剩下 40 分都是代码上的体力活了。
\(t=2\) 是要求 \((p_n,p_{n-1},\dots,p_1)\) 字典序最大,这就纯属把从后往前进行字典序贪心扔脸上了,也即每次删除最后一个加入的点。
我们考虑到,任意一个八连通块一定存在至少一个满足要求的排列,因此删除的点 \(x\) 只用满足两个条件:
- 条件一:将所有关键点按八联通建边,\(x\) 不是割点。
- 条件二:\(x\) 可以与「无限远的边界」四联通。
在 \(O(n^2)\) 的暴力中条件一是容易刻画的,考虑如何判断条件二。可以想到,我们将所有关键点八联通的 \(3\times 3\) 区域取出,在这些点中取「左上角」(最左边的点中最上边的一个),它不包含终点的路径上不经过关键点四联通能到达的所有点都是合法的点。
换而言之,一个关键点四联通的区域内存在空白点与「左上角」属于同一连通块,则该关键点满足条件二。
这样就可以非常容易地获得 60 pts 的高分。
要优化到 \(O(n\log n)\) 时,会发现条件二变得非常容易维护,只需要维护出每个空白点所属连通块标号即可,但条件一直接做要求动态维护圆方树,这是非常不可做的。
考虑网格图的特殊性质,会发现实际上的割点只有如下两种情况:
情况一:
| 0 | 0 | 0 |
|---|---|---|
| 1 | X | 1 |
| 0 | 0 | 0 |
0 表示空白点,1 表示关键点,X 表示待判断是否为割点的关键点,若所有 0 属于同一空白点连通块,则 X 为割点。
90 度翻转后同理。
情况二:
| 1 | 0 | 1 |
|---|---|---|
| 1 | X | 0 |
| 1 | 1 | 1 |
0 表示空白点,1 表示关键点,X 表示待判断是否为割点的关键点,若所有 0 属于同一空白点连通块,则 X 为割点。
90 度翻转后同理。
判断一下这两个东西即可。
P6361 [CEOI 2018] Fibonacci representations
平衡树狗都不写。
规定后文中的 Fibonacci 数列不包含 \(F_0=1\) 一项。
可以发现对于题目直接给出的拆分方案,如果存在一对相邻的 Fibonacci 数 \(F_i,F_{i-1}\),则即可以让 \(F_{i-1}\) 拆分为 \(F_{i-2},F_{i-3}\),也可以合并 \(F_i,F_{i-1}\) 为 \(F_{i+1}\)。
如果这样做,我们根本无法找到一个合适的顺序对 \(X(p_k)\) 进行计数。因此考虑不断进位使得 \(p_k\) 拆分出的 Fibonacci 数互不相邻,容易声称这样的拆分是存在且唯一的。
Lemma 0(齐肯多夫定理):称将一个数划分为若干不连续不相等 Fibonacci 数的方案为 Fibonacci 表示,则对任意正整数有 Fibonacci 表示存在且唯一。
Proof(数学归纳法):
对于正整数 \(m=1,2,3\),显然成立。
对于 \(m>3\),分类讨论:
- 若 \(\exists n\in\mathbb{N}_+,m=F_n\),则 \(m\) 有唯一 Fibonacci 表示为 \(m=F_n\)。
- 否则,设 \(n\) 为满足 \(F_n<m\) 的最大正整数,令 \(m'=m-F_n\)。则有 \(m'=m-F_n<F_{n+1}-F_n=F_{n-1}\)。由归纳假设,\(m'\) 存在唯一 Fibonacci 表示,且表示中最大数与 \(F_n\) 不为数列相邻项。
综上,命题成立。
拆分为这个形式之后,考虑将这个数按 Fibonacci 表示写成二进制串,然后尝试拆分最低位:
| \(F_1\) | \(F_2\) | \(F_3\) | \(F_4\) | \(F_5\) | \(F_6\) | \(F_7\) | \(F_8\) | \(F_9\) | \(F_{10}\) | $\dots $ |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | \(\dots\) |
| 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | \(\dots\) |
| 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | \(\dots\) |
| 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | \(\dots\) |
容易发现,当 \(F_{i}\) 被拆分为 \(F_{i-1},F_{i-2}\) 后,\(F_{i-1}\) 无法继续进行拆分,因此若 \(F_{i}\) 前 0 连续段的长度为 \(len\),则 \(F_{i}\) 至多存在 \(\lfloor\dfrac{len}{2}\rfloor\) 次拆分。
考虑下一个出现 1 的位置 \(F_{j}\),则若 \(F_{i}\) 进行过拆分,就有 \(j-i\) 长度的 0 连续段作为 \(F_{j}\) 进行拆分的空间,否则只有 \(j-i-1\) 的长度空间给 \(j\) 进行拆分。
容易发现相邻 1 之间方案转移很容易写成矩阵形式,也即:
那么使用平衡树维护所有为 1 的位置,并在节点上挂与其前驱的 1 的转移矩阵。
注意到动态加入新的 Fibonacci 数进行进位时存在势能,可以暴力维护。
P7214 [JOISC 2020] 治療計画
搬 luogu 老哥的图,考虑 \(T,N\) 两个维度构成的平面中,每个区间的效用是一个等腰直角三角形的范围。

题目的本质要求转换为选出若干三角形,使得 \(x=1\) 和 \(x=N\) 两条直线联通。对三角形建点,两三角形 \(i,j\) 存在连边当且仅当满足 \(R_i-L_j\geq |T_i-T_j|\)。注意这个连边关系与三角形是否相交无必然联系,如下图蓝色路径所示:

这个转移是可能存在环的,因此需要通过最短路求得答案。考虑进一步的优化,由于这是点权 Dijkstra,因此每个点至多被松弛一次,可以使用势能线段树维护。

浙公网安备 33010602011771号