DE_aemmprty 的草稿纸(2025.11.17 - NOIP 前)
关于难度
- Easy 1-3:我是 wht,我一眼秒了,我觉得这题没啥技巧啊!
- Medium 4-6:完全自己想出,但想了较长时间。
- Hard 7-9:不完全是自己想出。
\([0, 1]\) 表示在同档题中的难度。
ZR3436 Medium 4
思维
倒序考虑,如果最终操作的人是小 A,那当 \(n > 1\) 时,无论什么情况都可以变成 \(0\),故小 A 必胜。
先特判掉 \(n = 1\) 和最终操作的是小 A 的情况。
考虑小 A 和小 B 分别的决策。
-
小 A 会尽量让 \(0\) 多,让 \(1\) 少,那么如果有 \(\texttt{11}\) 就尽量操作成 \(\texttt{0}\),否则就是删 \(\texttt{1}\)。
-
小 B 会尽量让 \(0\) 少,那每次一定是删 \(0\)。
就按这种方式操作即可。
QOJ970 Hard 8
可持久化线段树 二分
考虑一个单次询问 \(\mathcal{O}(n \log n)\) 的做法,我们二分答案,假设当前二分的值是 \(W\)。
考虑 \(x + y \leq W\),\(\min\{x, y\} \leq \dfrac{W}{2}\),因此我们把所有数分成两类,若 \(a_i \leq \dfrac{W}{2}\) 就赋值为 \(1\),否则赋值为 \(0\)。
我们想要构造出恰好选择 \(k\) 个数的方案满足限制。如果我们选择尽量多的数,假设有 \(K\) 个,如果 \(K \geq k\),我们就需要删除一些数调整大小到 \(k\)。
我们可以先删除 \(0\),由于 \(0\) 两边一定都是 \(1\)(否则 \(0\) 和 \(0\) 相加一定 \(> W\)),删除 \(0\) 之后两边 \(1\) 相加一定 \(\leq W\)。如果没有 \(0\) 了,那么当前序列全都是 \(1\),随便删即可。
现在我们想选择尽量多的数,可以证明选择所有 \(1\) 一定是不劣的。
如果存在一种选择最多数的方案没有选择所有 \(1\),不妨设 \(a_i\) 是 \(1\) 且没有被选择:
如果 \(a_i\) 向左第一个被选择的数是 \(L\),向右是 \(R\),若这两个数有一个是 \(0\),则删除 \(0\),插入 \(1\) 一定可行。
否则说明两边都是 \(0\),直接插入即可。
因此,我们先选上所有的 \(1\),那相邻两个 \(1\) 最多只能插入一个 \(0\),我们判断一下这段区间中的 \(a_i\) 最小值能否插入即可。单次询问时间复杂度为 \(\mathcal{O}(n \log V)\)
对于每个区间 \([L, R]\) 以及二分的 \(W\),我们要能够快速的计算出最多选的数的个数。也就是说,我们要快速计算这段区间中,相邻两个 \(1\) 中最小值能插入的相邻对个数。
反过来,我们考虑一个二元组 \((i, j)\) 对于所有 \(1 \leq W \leq 2V\) 的贡献。也就是说,哪些 \(W\) 满足 \((i, j)\) 是相邻的两个 \(1\),且中间的最小值能插入。
从小到大枚举 \(j\),考虑哪些 \((i, j)\) 能造成贡献。对于一个 \((i, j)\),要造成贡献,需要满足 \(a_{i + 1}\) 到 \(a_{j - 1}\) 的最小值大于 \(a_i\) 和 \(a_j\)。
我们处理出从小到大的单调栈,那么容易发现 \(a_i\) 必须是单调栈上的数,且 \(a_i\) 在单调栈上的下一个数要大于 \(a_j\)。很显然,这就是将 \(a_j\) 插进单调栈后被弹出的那些数,因此这样的二元组只有 \(\mathcal{O}(n)\) 个。
对于每一个二元组 \((i, j)\),假设中间的最小值下标为 \(k\),那么我们要看贡献的区间是什么。显然有 \(a_i + a_k \leq W, a_k + a_j \leq W\) 和 \(a_k > \dfrac{W}{2}\),则 \(W \in [a_k + \max\{a_i, a_j\}, 2a_k)\)。这个可以使用可持久化线段树维护。
因此,询问要求 \([L, R]\) 的答案,那我们找到左右的赋值为 \(1\) 的下标 \(lx, rx\),然后计算 \(s_{rx} - s_{lx}\) 的值,与 \(k\) 比较即可。注意由于答案是环,需要特殊考虑首尾相接的情况,因此还需要一个 ST 表。
KEL9762 Medium 6
可持久化线段树 线段树优化建图 最短路
考虑对于每一行网格,把网格上的格子划分成没有障碍物的极长段。对于每一列同理。
如果一行和一列有交点,那就连一条边。我们根据这个图跑一边最短路。
然后考虑 \((i, j)\) 这一个点,它一定被一个行连续段和一个列连续段包含,而且显然这两个连续段的最短路之差小于等于 \(1\)。
先考虑如何建图,我们从上往下扫每一行,线段树存储目前每一个位置所在的列连续段编号。然后,显然一个行连续段与一段列连续段区间有连边,因此使用可持久化线段树优化建图即可。
对于统计答案,我们只需要计算行最短路和列最短路不同的格点数即可。考虑从上往下扫行,维护若干个 set,\(s_i\) 存储列最短路为 \(i\) 的格点,然后对于一个行连续段,找到在这个区间中与该行最短路相等的格点个数即可。
KEL9317 Medium 5
容斥 树上 DP 线段树合并
考虑容斥,设两端相等的边的集合为 \(S\),那就是这种情况的方案数,带一个 \((-1)^{|S|}\) 的系数。
首先我们显然可以把已经固定的数 \(a_i\) 的范围压到 \([1, n]\)。
然后考虑 DP,设 \(f_{i, j}\) 表示以 \(i\) 为子树,当前 \(i\) 所在的连通块颜色为 \(j\)。(如果该连通块全是 \(a_i = 0\),那 \(j\) 为 \(0\))
转移就是考虑新加入的子树 \(v\) 向 \(u\) 的边是否两端颜色相同,如果相同,就连通块合并,否则乘上 \(v\) 连通块的情况数。
考虑优化,由于这个 DP 转移不是特别复杂(基本没有同时涉及到 \(x, y\) 的转移方程),因此考虑线段树合并来优化即可。
KEL1287 / P12503 Medium 5
二分 三分 函数最值

KEL9516 Easy 3
动态规划 二分 线段树 单调栈
设 \(f_{i, j}\) 表示前 \(i\) 个文件夹,当前只需要 \(j\) 行,最小的宽度,转移就是枚举新的一列用了 \([i + 1, k]\) 的文件夹,复杂度 \(\mathcal{O}(n ^ 3)\)。
考虑优化,我们可以二分最多需要多少行,这样定义 \(f_i\) 表示前 \(i\) 的文件夹使用 \(mid\) 行的最小宽度,复杂度就是 \(\mathcal{O}(n ^ 2 \log n)\)。
观察转移式子 \(f_i = \min\limits_{i - mid \leq j < i} \{f_j + \max\limits_{j + 1 \leq k \leq i}\{a_k\} + 1\}\)。
考虑线段树优化,维护一个单调栈,然后使用线段树维护 \(f\) 的值即可。

浙公网安备 33010602011771号