IOI 2026 国家集训队作业简单题选做
如果这篇文章对你有帮助,可以点个赞支持一下 /kel
如果觉得我写的有问题,请洛谷私信 @Purslane。
目前的问题:Qnp 这道题被叉了(代码似乎完全错误),还不知道是啥情况;Stone Catch Game 有一点说不明白充分性(顺便,这道题我的代码是 \(O(n^2)\) 的,不过是目前的最优解)。别急。
1. QOJ833 Cells Blocking
先考虑这样一个问题:有多少个格子,删掉之后不存在 \((1,1) \to (n,m)\) 的路径。
注意到每个 \(x+y=c\) 的对角线上至多一个格子是必经的,尝试把它们处理出来。如果我们能求出这些格子中能被经过的最左边的格子,以及能被经过的最右边的格子(同一对角线上)。如果这两个格子相同,这个相同的格子就是必经;否则任何一个格子都可以不被经过。
如果我们选的两个格子都不能直接阻挡 \((1,1) \to (n,m)\),那么一个格子必定在 \((1,1) \to (n,m)\) 的最靠左的路径上,我们考虑枚举 \((x_0,y_0)\) 并将其删掉,这时候要重新计算 \((1,1) \to (n,m)\) 的最靠左的路径。那么显然,最靠左的路径一定会经过 \(x+y=x_0+y_0\) 的、在 \((x_0,y_0)\) 右边但是又能被路径经过的最靠左的格子(长难句起手)。这条路径可以 \(O(n+m)\) 确定。因此我们在 \(O((n+m)^2)\) 的复杂度内解决了本题。
2. QOJ837 Giant Penguin
很久之前看过这个技巧,现在有点忘了。
考虑点分治,求出原图的一个生成树 \(T\),在 \(T\) 上点分治。在分治集合 \(S\) 的时候,考虑点 \(u\) 如何对点 \(v\) 贡献答案。
如果 \(u\) 和 \(v\) 在同一子树内(分治中心为 \(r\) 时),\(u \to v\) 有两种情况:只用 \(S_0\) 的点及其内部的边(\(S_0\) 为包含 \(u\) 的子树),这在递归中会被处理;用了 \(S_0\) 外面的边,那么一定经过了 \(r\),或者某个包含 \(r\) 的环的非树边。\(u\) 和 \(v\) 不在同一个子树内,也是要么经过 \(r\) 要么经过某个包含 \(r\) 的环的非树边。
而这些边只有 \(10\) 条,我们可以钦定经过这些环的端点来解决所有情况,复杂度 \(O((n+m)k \log n)\)(原因是,钦定经过环的端点只需要 BFS)。
代码写完直接编译通过!已无敌!
3. QOJ850 Edit Distance Yet Again
神中神题!引用我看到的一句话:和这种题生在一个时代是我的荣幸!!!
首先,使用网格图的最短路刻画编辑距离。即设 \(dp_{i,j}\) 为 \((i,j)\) 的答案,则:\(dp_{i,j} = \min \{dp_{i-1,j-1}+[S_i=T_j],dp_{i-1,j}+1,dp_{i,j-1}+1\}\)。
结论:如果 \(dp_{i,i+\delta} = dp_{j,j+\delta}\),且 \(i<j\),那么 \(i\) 一定没用。
具体的,考虑 \((i,i+\delta) \to (n,m)\) 这条路径,与 \(j\) 的交点。

绿色这一段的代价一定大于等于紫色这一段的代价,因此 \((j,j+\delta) \to (n,m)\) 的最短路一定 \(\le (i,i+\delta) \to (n,m)\) 的最短路!
因此 \((1,1) \to (i,j)\) 最短路为 \(k\) 的点至多 \(O(k)\) 个有用的(因为它至少要走这么多不是 \((x,y) \to (x+1,y+1)\) 的边,而这些边一定会带来 \(+1\) 的贡献),因此暴力维护这些有用的点就做到了 \(O(Tk^2 \log k)\)(我们在代价为 \(0\) 的时候尽量往后扩展,也就是贪心选 lcp。使用后缀数组可以做到 \(O(Tn + Tk^2)\),但是首先我不会 \(O(n)\) 后缀排序,其次时限 20s,一点不带怕的)。
最后思考一下怎么输出。只需要把最短路径给找到,从后往前处理(处理所有边权为 \(1\) 的边就好。在第二个字符串删可以看做第一个字符串插入)就行。
4. QOJ856 Cactus
怎么真有集训队选签到题的。
让 whk 同学品鉴了一下题面的前两段话,得出结论——一股浓浓的读后续写味(诡异的动作描写,尬的不能再尬的修饰性语句)。但是他说 overwhelmed with sorrow 是高中英语的常见表达,我咋不知道??
限制是 \(\sum_{(u,v) \in E}[c_u=c_v]=0\),对其施容斥原理,钦定一些边满足 \(c_u=c_v\)。
假设钦定了 \(c\) 条边,其中 \(k\) 个环被全部选中,则自由度是 \(p^{n-c+k}\)。发现贡献可以拆开,每个环分别做一遍即可。
6. QOJ862 Social Justice
大家都快是成年人了,能不能别写普及题了。
就是说,你固定最大值之后,你只需要平均值 \(\ge\) 某个数。选取最多的数使得平均值 $\ge $ 某个数,这是贪心。
假设贪心的时候最优解集合是 \(S\)。我们想判断另一个数是否在集合里面,只需要去掉 \(S_{\min}\) 并且把它加进去,对它只有下界限制,二分 + 前缀和即可。
8. QOJ888 Travel around China
如果有向网格图最短路问题,很容易让人想到分治,但是这题有两个问题:
- 网格并不是单向的;
- 询问达到 \(O(m^2)\) 量级,而对网格进行分治最关键的一步就是扫描短边,每个询问都要做一次。
由于网格并不单向,所以你就不能“分治”。但是你观察发现 \((x_1,y_1) \to (x_2,y_2)\)(\(y_1<y_2\)),则 \(y_1 \to y_2\) 的部分是单调的。
也就是说,我们预处理 \(f_{i,o_1,o_2}\) 和 \(g_{i,o_1,o_2}\) 表示 \((o_1,i)\) 只使用其左边的格子到达 \((o_2,i)\) 的最短距离,与只使用右边格子的最短距离,那么就变成了单向的网格问题,这时候分治就是对的。
接着怎么处理“扫描”。相当于给你 \(p_{1,2,3}\) 和 \(q_{1,2,3}\),让你求 \(\min_{1 \le i \le 3} \{p_i+q_i\}\)。这个问题有一个学名叫做《如何正确的排序》,直接上二维偏序就好了。
总复杂度为 \(O(m \log^2 m)\)。为什么我的代码这么慢,是不是有黑幕 /fn
9. QOJ962 Thanks to MikeMirzayanov
显然我们可以完成“翻转”操作。因此,我们把原问题改写为:将序列划分为若干段,每一段分别翻转。
如果序列只有 \(01\),显然可以在 \(O(\log n)\) 次操作内排好序。而容易发现若干段区间的排序是可以并行的,因此容易做到 \(O(\log^2 n)\)。
10. QOJ964 Excluded Min
很帅。首先,考虑用一个好看一点的算式来刻画答案。
注意到答案是 \(v\) 的时候,集合中 \(\ge v\) 的数应该对答案没有影响——如果从在一个 \(j\) 由 \(i\) 转化过来(\(j<i\)),则 \(\forall j \le k \le i\) 原序列中都应该至少有一个 \(k\)。
也就是说,\(\sum_{u \in S} [u<v] \ge v\) 即可。这就是题目中所说 \(O(n \sqrt \log n)\) 做法来源:直接莫队,用线段树维护每个 \(v\) 的答案(注意答案一定 \(\le O(n)\))。
考虑从大到小扫描 \(v\),对每个 \(S\) 维护 \(\sum_{u \in S} [u < v] - v\) 的值,以及最大值。每次检查最大值是否 \(\ge 0\),如果最大值 \(\ge 0\) 就认为 \(S_{\max}\) 的答案是 \(v\),将其从数据结构中删掉。
而 \(v\) 变化时,对 \(S_i = [l_i,r_i]\) 的影响是:若 \(l_i \le u \le r_i\)(其中 \(a_u=v\)),则 \(f(S_i) \leftarrow f(S_i)-1\)。对应的 \(i\) 的范围在平面上是一个矩形,大概率做不明白(KDT 只能做到根号)。
如果只维护那些极长的、不被另一个线段包含的线段(显然被包含,包含者会被更早删掉),由于 \(l\) 和 \(r\) 都是单调的,对应的 \(i\) 范围就是一个区间!那么本题就在 \(O(n \log n)\) 的复杂度内被解决了。
15. QOJ993 100 Boxes Per Hour...
有点神秘,可以扔过去当 MO 题。
先考虑一个简单的问题:如果只有一个盒子,两种颜色,怎么维护?假设两种球分别有 \(A\) 和 \(B\) 个(\(A \le B\)),那么可以做到 \(\max(A,B-A) \ge \frac{A+B}{3}\)(如果 \(A\) 更大你就直接加一个元素。否则你先存一个元素,看两种球谁先到 \(A+1\),先到的就是 \(B\))。注意这样做非常依赖于你知道 \(A\)、\(B\) 的值。
原题中设 \(A \le B \le C\),显然有 \(A+B\) 的方法,所以设 \(A+B \le 42\),\(C \ge 58\)。
考虑放 \(B\) 和 \(C\),容易构造出一种 \(C-A+B-A=100-3A\) 的方法。注意这里保证了 \(A \le 21\),可以做到 \(37\)。
这里的问题出在 \(A \ge 20\) 的时候,你可以认为 \(B \sim A\)。这时候又显然存在 \(C-B+A\) 的做法,成功搞定。
16. QOJ1166 Designing a PCB
看起来像 2-SAT 模型,但是你发现两个点之间本质有 \(8\) 种连法,而如果每个点分配一个布尔变量只能搞定 \(4\) 种,这咋办。
我们想要把一些状态调整到他们的补。一个连线本质把点划分成了两部分(点从上方连出边与从下方连出边本质上是不同的点)。

如果红蓝的冲突是这样的,那么及时把绿色变为补也没用。

另一种冲突是这样的。

我们发现,一定不会出现这种连线,将其调整为它的补更优。

而跨过一边的连线,发现让它都跨过电路板的某一端点最优(这里把蓝色调整一下就对了)。
而且不需要考虑整体跨过左边与整体跨过右边,他们完全相同,这样你就能使用每个点一个布尔变量来弄这道题了!!类似 NOID1T3 的某个神秘 \(80\) 分做法,只需要每一对 \((i,j)\) 都没有矛盾就行。不妨设 \(L_i<L_j\),分几种情况:
- \(R_j<R_i\)。这样等价于 \(L_j\) 和 \(R_j\) 方向相同。
- \(R_j<L_i\)。没有任何限制,一定没有矛盾。
- \(R_j > R_i\)。这样等价于 \(L_j\) 和 \(R_i\) 方向相反。
这个 2-SAT 模型是“无向边”,使用并查集维护即可。
19. QOJ2351 Koosaga's Problem
有点切边等价的感觉。当然我认为可以通过暴力分类讨论得到确定性做法(\(|S| \le 1\) 是容易的,\(|S|=2\) 按照 DFS 上树边被删掉的边是 \(0/1/2\) 条,\(2\) 条再分是否有祖孙关系)。
考虑找出一棵生成树之后,分析所有非树边。如果有一条 \(u \to v\) 的非树边,我们赋上 \(w\) 的权值,则在 \(u \to v\) 的路径上也赋上 \(w\) 的权值。则奇环会导致整体异或和多 \(w\)。
容易分析得知,图是二分图等价于所有边权异或和为 \(0\)(显然等价于所有非树边都不在奇环上。这里是必要条件,充分性有误的概率为 \(2^{-64}\))。
这时候可能有聪明宝宝就说了——啊主播主播,直接删掉 \(0/1/2\) 条边让新图的边权异或和为 \(0\) 不就行了嘛!这么写代码发现,唉确实一发通过了。但是你有没有想过:如果这样真的对的话,为什么本题只让你求“最小”?
问题出在,删掉一条边之后可能会使非树边变成了树边,这样就不满足上文的赋权方法了。
比如,原图不是二分图,删掉一条边是二分图,那么会发生什么?删掉的这一条边,一定会在至少一个奇环上,而且不能在任何一个偶环上。因此删掉这条边之后,如果有一条奇环的非树边变成了树边,它原有的贡献会给新图(其实都是树边)偶数条边产生影响,等价于没有影响。
而如果原图就是二分图,很容易构造反例使得这个做法不对(比如一个简单环)。
20. QOJ1355 Rhythm Game
记 \(dp_{i,j}\) 为,前 \(i\) 个音符点了 \(j\) 个的最大收益,且第 \(i\) 个音符没有点。
容易发现,我们会按照 \(i-j\) 的顺序分层转移,且拥有决策单调性。注意如果你认为从 \(dp_{i-1,j} \to dp_{i,j}\) 的代价是 \(0\) 的话,它和其他的决策之间不存在单调性。
复杂度 \(O(n^2 \log n)\),代码很好写。
24. QOJ1812 Interesting Coloring
建出一棵 DFS 树,我们控制根到每个叶子的颜色个数不超过 \(7\) 即可。
考虑确定了 \(1 \to u\) 的颜色,现在要确定 \(u \to v(\in son_u)\) 的颜色。贪心的让那些 \(sze_v\) 大的节点颜色在 \(1 \to u\) 的路径上已经出现即可。
我也不知道为啥对(显然答案不会太大,为什么这样能卡进 \(7\) 我也不清楚,可以打表算一下)。
27. QOJ1817 AND Permutation
考虑对 \(\text{highbit}\) 归纳构造解。
我们要处理 \((a_1,a_2,\cdots,a_n)\) 时,把最高位为 \(1\) 的数扔到 \(L\) 集合中(同时删去最高位),最高位为 \(0\) 的集合扔到 \(R\) 集合中。容易发现,\(L\) 和 \(R\) 仍然满足条件,我们归纳构造出一组解。
尝试把 \(L\) 的最高位加回去,由于 \(L\) 的解都在 \(L\) 内部,实际与起来不一定为 \(0\)。但是注意到 \(L\) 中每个元素在 \(R\) 中都有对应,交换一下即可。
28. QOJ1823 Permutation CFG
有一点意思的基础题。由于 \(s \le 5\),因此我们可以分析这个前缀在每一层“没有取干净”的区间是哪个,这个区间可以使用线段树上二分算出来。注意到不同的区间只需要限制“保留 \(\le v\) 的数”,所以可以通过一个量来限制。
然后就相当于计算一段区间中多少个数 \(=v_0\)。如果 \(v\) 分裂 \(k\) 次到 \(v_0\) 有 \(\dbinom{v-v_0+k-1}{k-1}\) 种方案(\(k \le 4\)),当固定 \(v_0\) 的时候这是关于 \(v\) 的一个低次多项式。你使用线段树(准确来说是一个二维偏序,对时间轴使用扫描线)之后相当于单点修改,区间查询二次方、三次方、四次方和。
代码有一点点难写,不过 QOJ 种存在一些很好看的代码,可以学习。
30. QOJ1825 The King's Guards
考虑确定所有守卫在哪个节点之后,如何计算最小代价。这时候的问题与 P6789 非常类似,使用。可以知道具有拟阵结构,并且有用的边都在最小生成树上(最开始对每个 \(2 \le i \le n\),加上 \((1,i,+\infty)\) 的边)。
一组边合法,当且仅当可以构建守卫到连通块的单射,可以使用网络流判定。由于拟阵的性质,可以每次贪心加入边权最小的边看是否仍然合法。使用匈牙利算法,单次增广复杂度为 \(O(ng)\),因此可以在 \(O(n^2g)\) 的复杂度内解决本题(个人认为网络流退流也是可以的,但是复杂度保持不变)。
另一种想法是,给定一组守卫之后可以判断一条边是否会出现。一条边 \(r\) 如果在 Kruskal 的过程中合并了 \(S\) 和 \(T\) 两个连通块,这条边会出现当且仅当 \(S\) 和 \(T\) 中至少存在一个不含有守卫者。所以,可以先把 \(r\) 加到答案里。如果 \(S\) 中存在守卫者,产生 \(-r\) 的贡献;\(T\) 中存在守卫者,产生 \(-r\) 的贡献,\(S \cup T\)(也就是 Kruskal 重构树上的新集合)中存在守卫者产生 \(r\) 的贡献。
问题抽象为:给你一棵树,树上有点权。你要选若干叶子,使得叶子到根路径的并中所有点的点权和最小。
直接做是不可能的,但是根据 Kruskal 重构树的特性,所有点的点权 \(\le 0\)。因此可以用费用流模型刻画。
有负权的费用流可以类似上下界网络流处理。
31. QOJ1839 Joke
题解在写啥啊?考虑如何判断一组 \((p,q,s)\) 是否正确:正确等价于建立出偏序关系后的图没有环。那么对着不出现环的情况,判断
注意 \(s\) 的每一位都对应了一条边,而 \(s\) 只是给他们定了个向。保证任意两条边都不成环即可,对定向方案计数。

我们考虑具有“最……”特性的边,在这里选取的是“下层对应点最靠后的边”,即题目中的红边。
如果是指向上层点的,那么这条边一定不在环上;如果指向下层点,那么所有上端点在其右侧的点也工改指向下层点(蓝边)。

然后容易发现设 \(p_i\) 为上层第 \(i\) 个点对应下层的点的位置,则一组定向方案和 \(p\) 的一个上升子序列对应。相当于对所有的 \(q\),计算上升子序列的个数和。
这个随便做就是 \(O(n^3)\) 的了。
32. QOJ1840 K-onstruction
我不会,大家都太厉害了 ww
这题的核心想法是:如果存在 \(K=K_0\) 的解,能否操作操作变为新的数 \(K=K_1\) 的解。
强化 \(S\) 的条件:\(S\) 中不存在 \(0\) 且 \(\sum_{u \in S} u \neq 0\)。不妨设 $\sum_{u \in S,u > 0 } u = P $ 且 \(\sum_{u \in S} u = 0\),那么集合 \(S_0 \subseteq T\) 使得 \(P \mid \sum(S_0)\),这样的 \(S_0\) 只有两种情况:\(\sum(S_0) = P\) 和 \(\sum(S_0) = -P\),且 \(P \nmid \sum(S)\)。
找到 \(T\) 使得 \(T\) 中所有元素都是 \(P\) 的倍数。令 \(S_1 = S \cup T\),则 \(S_1\) 拥有和 \(S\) 相同的限制,并且和为 \(0\) 的集合很容易:从 \(T\) 中选一个权值和是 \(0\) 的子集,与 \(S\) 权值和为 \(0\) 的子集拼在一起;或者从 \(T\) 中选取一个权值和是 \(-P\) 的子集,与 \(S\) 中权值和为 \(P\) 的子集拼在一起。
题目证明了,只取 \(T \subseteq \{-3P,-2P,-P,P,2P,3P\}\) 是能满足题目要求的。
因此我们在 \(O(n)\) 的复杂度内解决了本题!!
36. QOJ1875 Nein
如果你想分析 \(x\) 有什么特征大概是死定了,因为进位关系太复杂,找不到统一的形式。
而分析一个数是否为 \(10^k-1\) 的倍数,往往比较容易。由于 \(10^k \equiv 1 \pmod {10^k-1}\),所以我们可以将这个数按照 \(k\) 分段并且求和是 \(10^k-1\) 的倍数即可,这里分段本身就是关于数位的,更容易处理是否存在 \(9\)。
瞎猜一手这样的数不是很少,也就是最终答案用 int128 存的下,也就是 \((10^k-1)x\) 最多 \(B\) 位。然后逐位确定答案,需要计算 \(10B\) 次。每次数位 DP,要进行 \(\frac{B}{k}\) 轮,每一轮有 \(k\) 位,每一位有 \(\frac{10B}{k}\) 种方案,再加上进位的 \(\frac{B}{k}\) 种,总复杂度为 \(10B \times \frac{B}{k} \times k \times \frac{10B^2}{k^2} = \frac{100B^4}{k^2}\)。据说 \(\frac{B}{k} \le 20\),也就是 \(40000B^2\)。显然 \(B \le 50\),勉强能接受。
41. QOJ2214 Link Cut Digraph
经典的《WD 与地图》。使用整体二分求出:每条边的两个端点处于同一个 SCC 的最早时间。这样有向边变成了无向边。
42. QOJ2548 Juggler's Trick
首先归纳证明:只要一个序列长度为 \((r+b)\) 的倍数,而且 \(\frac{cnt(\texttt R)}{cnt(\texttt B)} = \frac{r}{b}\),一定可以将其消完。
大致想法是,只需要证明能消一个。使用离散介值定理即可(根据平均值原理,必有两个 \((r+b)\) 长度的段,一个 \(\texttt R\) 的个数 \(\le r\) 一个 \(\ge r\),他们之间离散介值一下)。
怎么判断一个区间是否合法呢?只需要:\(\texttt R\) 占比 \(\le \frac{r}{r+b}\),\(\texttt B\) 占比 \(\le \frac{b}{r+b}\),区间长度是 \((r+b)\) 的倍数。
把最后一个限制拆开,可以使用 KD Tree、二维线段树(我不会)、CDQ 优化 DP,复杂度 \(O(n \log^2 n)\)。
那些 1.2 Kb 写完的诗人??
44. QOJ2554 AND PLUS OR
考虑通过调整使得 \((i,j)\) 对比较好看。
不妨设 \(|j / i| \ge 2\),我们证明,可以找到 \((i',j')\) 使得 \(|j'/i'| < |j/i|\)。这样,如果存在合法的 \((i,j)\),一定存在合法的 \((i,j)\) 满足 \(|i \oplus j|=2\)。
证明:不妨设 \(i = ab\),\(j=bcd\)。根据定义,\(f(ab)+f(bcd) < f(b) + f(abcd)\)。
如果 \((i',j') = (ab,bc)\) 和 \((i',j') = (abc,bcd)\) 同时不对,则 \(f(ab)+f(bc) \ge f(b)+f(abc)\),\(f(abc)+f(bcd) \ge f(bc) + f(abcd)\)。两式相加得到 \(f(ab)+f(bcd) \ge f(b) + f(abcd)\),矛盾。
而这样的 \((i,j)\) 显然只有 \(O(n^22^n)\) 对,即证。
46. QOJ2570 Maximal Subsequence
使用颠倒偏序关系后 RSK 算法得出的杨表是原杨表的转置,容易规约到洛谷 P7931 上。
先给出本题的大致思路:
- 先将序列去重,使得所有数互不相同(如果 \(a_i=a_j\) 且 \(i<j\),去重之后 \(a'_i > a'_j\)。这一步可以使用对 \((a_i,-i)\) 二元组排序实现)。
- 记 \(f_i\) 为以 \(i\) 结尾的最长上升子序列的长度,并以此对序列分层。记序列的答案是 \(m\),则我们取出的子序列 \([x_1,x_2,\cdots,x_m]\) 有 \(f_{x_i}=i\)(\(1 \le i \le m\))。
- 贪心选出所有最长上升子序列中,字典序最小的那一个(是下标字典序最小),并将其从原序列中删掉,直到选出的序列的长度 \(<m\)。选字典序最小的最长上升子序列的方法为:用
set维护每一层现存元素,并且暴力 DFS;DFS 的过程中,判断以 \(pos\) 为开头的最长上升子序列(\(\ge pos\) 所在层的每一层恰选一个)能否延伸到第 \(m\) 层,如果不能直接将其删掉。显然该算法复杂度为 \(O(n \log n)\),每个点在 DFS 过程中只会出现一次。
47. QOJ2601 Lucky Tickets
感觉没经历过什么大事出不出这种神经病题目。
首先,考虑固定 \((a_1,a_2,\cdots,a_n)\) 的无序集合。计算无序集合所有可能的排列,\(f_S = \sum_p \prod_{u \in S} a_{p_u}\)。考虑所有无序集合的权值之和,发现 \(|S| \le n-2\) 铁定没有贡献(使用牛顿幂和公式,拉格朗日公式和数学归纳法),\(|S| = n-1\) 的贡献非常神奇的与后面那一大坨东西抵消掉了。所以你甚至可以直接把 \(\prod a_i\) 当作贡献。
如果 \(a\) 并不全相同,多重组合数肯定是 \(q\) 的倍数。所以枚举全相同等于 \(a_0\),可以做到 \(O(n \log V)\)。
49. QOJ2606 Gachapon

原神,启动!由于所有位置本质相同,所以只需要算出 \(P(第 i 个位置抽了 v,且整体合法)\)。条件概率拆开,写作 \(P(第 i 个位置抽了 v) P(若第 i 个位置抽了 v,整体合法的概率)\)。后者可以设计 DP 为:已知第 \(i\) 抽的最大值是 \(j\),整体合法的概率。发现这个还要算第 \(i\) 抽合法时最大值为 \(j\) 的概率。总之使用 max 卷积容易 \(O(nm \log b)\) 搞定。
52. QOJ4241 Angle Beats 2.0
注意到必定是 \(\tt {UD}\) 二选一,\(\tt {LR}\) 二选一。把“二选一”的结构使用无向边刻画(如果有一个不行,在另一个节点上连自环)。
则我们需要给无向边定向,使得每条边的入度至多为 \(1\),计算方案数。
考虑一个弱连通分支,则 \(m \le n\)。因此弱连通分支只能是树或者基环树。
而基环树有 \(1\) 或 \(2\) 种定向方法(区别在于是否有自环),树有 \(n\) 种定向方法,全部乘起来即可。
53. QOJ4243 Good Coloring
神秘。将边按照颜色进行定向之后求最长路,显然最长路数组符合要求。
54. QOJ4786 Balance
显然这个矩形只有 \(2n\) 个自由度——存在整数序列 \(x\) 与 \(y\) 使得 \(a_{i,j} = x_i+y_j\)。
我们要最小化 \(\sum_{i=1}^n x_i+y_i\),看他能 \(\ge\) 某个数。发现可以找一个排列 \(p\),由于 \(x_i+y_{p_i} \ge a_{i,p_i}\),所以 \(\sum_{i=1}^n x_i+y_i \ge \sum_{i=1}^n a_{i,p_i}\)。我们对所有的 \(p_i\) 求最大值,容易使用二分图最大权匹配搞定。
假设求出一组二分图最大权匹配。我们不妨设 \(i \to i\) 这样匹配。则 \(x_i+y_i=a_{i,i}\),所以自由度变为 \(n\)!!
那么有 \(x_i+a_{j,j}-x_j \ge a_{i,j}\),即 \(x_j \le x_i + (a_{j,j}-a_{i,j})\)。转化为差分约束模型。
容易发现这样不存在负环(根据匹配的最大性,如果存在负环那么存在更优的 \(p\)),在 \(O(n^4)\) 的复杂度内搞定。
56. QOJ4793 Qnp
容易猜测,相同数的连续段只有 \(O(\text{polylog}(n,k))\),每一段分别二分就行了,注意处理 \(>K\) 的数。
65. QOJ6104 Building Bombing
线段树优化 DP 模板题。
66. QOJ6284 Routes
挺不错的简单题。
如果飞了至少一次,那么可以维护 \(dis_{u,c}\) 为城市 \(u\) 到区域 \(c\) 的最短距离,则 \(\text{ans}_{u,v} = \min_{c} dis_{u,c}+dis_{v,c}+1\)。由于答案存在显然的上界,不飞的情况很少,可以暴力修改。
容易观察到,\(dis_{u,c}\) 大概只和 \((col_u,c)\) 有关,且 \(dis_{u,c}\) 对于 \(col_u\) 相同的点极差不超过 \(1\)。现在对于一对 \((col1,col2)\) 计算答案。
我们先求出 \(val=\min_{c} dis'_{col1,c}+dis'_{col2,c}\),显然 \(\text{ans}(u,v) \in \{val,val+1,val+2\}\),那么分别计算这三个有多少种情况。可以魔改一下各种位运算卷积的操作弄。复杂度 \(O(k^3 2^k + \text{poly}(n,k))\)。我卡了一年常。
67. QOJ6537 One, Two, Three
反悔贪心是不会的,来一个力大砖飞的做法,\(O(n \log^2 n)\),在卡常后能够通过。
注意到 \((\texttt{121},\texttt{323})\) 一定可以重新组合成一组合法对,因此只需要 \(1\) 和 \(3\) 的总个数相同,\(2\) 都在中间。
首先二分答案,如何判断答案 \(\le m\)。注意到我们一定会选恰好 \(m\) 个 \(\texttt 1\) 和 \(\texttt 3\)。假设我们希望 \(k\) 个 \(\tt 1\) 在前面,\(m-k\) 个 \(\tt 3\) 在前面。那么一定选择的是“最前面”与“最后面”的。假设我确定了前面的集合为 \(S\),考虑 \(f(S)\) 为他们匹配的最早的 \(\tt 2\)(这步贪心是显然的)。
结论:如果 \(T = S / \{u\}\),那么 \(f(T) = f(S) / \{v\}\),也就是说我们动态维护 \(S\) 和 \(f(S)\) 是可行的(具体而言,使用线段树 + set 的二分实现)。此时只需要每个 \(\tt 2\) 都能往后匹配一个元素就行,还是转为 \(\pm 1\) 序列使用后缀和的最小值刻画,复杂度 \(O(n \log^2 n)\)。
68. QOJ6538 Lonely King
略加调整容易发现:最优的方案一定是将树剖分为若干非叶子节点与叶子节点的链(每条边恰好在一条链上),即只有非叶子节点到叶子结点有贡献。而且,任何 \(2 \le u \le n\),\(u\) 子树内恰有一个叶子要和子树外的点产生贡献。
设 \(dp_{u,i}\) 表示,考虑 \(u\) 为根的子树,往外产生贡献的点权值为 \(i\) 的最小代价。
发现转移就是:
直接弄需要线段树合并 + 凸包啥的,看起来不太能做。考虑把下标当做斜率扔进李超树里面,发现只有打 tag(因为整体截距增加没有影响)和合并。直接上李超树合并复杂度为 \(O(n \log n)\),但是我比较懒写了启发式合并的 \(O(n \log^2 n)\)。
有集训队写不明白李超树。
69. QOJ6540 Beautiful Sequence
答案是:\(n - \sum_{i=1}^{n-1} [x_i \neq x_{i+1}] + \sum_{i=2}^{n-1}[x_{i-1}>x_i<x_{i+1}]\)。
首先猜测:所有相同的数形成一个连通块。分析后发现,只需要不是所有的 \(x_i=c\) 都满足 \(2 \le i \le n-1\) 且 \(x_{i-1}>x_i<x_{i+1}\),调整到一个连通块肯定更优。
考虑从大到小加数,维护当前连通块。那么只有两个选择:
- 当前数形成一个连通块,连通块个数加一(影响第二个式子);
- 合并 \(cnt+1\) 个连通块为 \(1\) 个(影响第三个式子和第二个式子),即连通块个数减 \(cnt\)。
问题转化为:给定 \(c\)。你可以将若干个 \(a_i\) 设为 \(c_i\) 其他为 \(0\)。在满足 \(\sum_{j=1}^i a_j \le i\) 恒成立的情况下最大化非 \(0\) 数的个数。
这我哪会啊,但是瞎写一个反悔贪心过了,思考一下感觉挺对(即设 \(S(p)\) 为前 \(p\) 个数的最优答案,那么给定 \(S(p-1)\) 一定能找到一个 \(S(p)\) 使 \(|S(p) \oplus S(p-1)| \le 2\),这就是反悔贪心的过程)。
一场比赛两个反悔贪心有点不是人。
73. QOJ6555 Sets May Be Good
原题是 ABC220H。
使用 bitset 维护即可(因为对列的操作本质是容易的,列的起点都是唯一的)。
为啥我没退役的时候写不明白这个 bitset 呢,还是太菜了。
74. QOJ7412 Counting Cactus
对着圆方树 DP 就好
直接状压,用一些简单的手段避免算重。复杂度大概是 \(O(n^3 3^n)\)。集训队作业中的题解复杂度似乎为 \(O(n^2 3^n)\),很厉害。
76. QOJ7416 Grammarly
设 \(dp_{l,r}\) 表示从 \(S[l,r]\) 到某个字符串的路径数。
发现,只要 \(S[l,r-1] \neq S_[l+1,r]\),即 \(S[l,r]\) 种字母不全相同,就可以转移到 \(dp_{l,r-1} +dp_{l+1,r}\);否则,转移到 \(dp_{l,r-1}\)(其实这时候答案就是 \(r-l+1\) 了)。
相当于你有两个标记,刚开始处于 \(1\) 和 \(n\)。你可以移动他们(任意时刻停止,重合必须停止),但是当两个标记中的字符全相等的时候只能移动右标记。
只需要用全部的移动方法,减去不合法的移动方法即可。
82. QOJ8085 Bulbasaur
有趣!先考虑怎么计算 \(f(1,n)\),相当于要计算最大流。
我们从后往前推。每一层哪些节点被经过是独立的,因此设 \(f_{i,S}\) 为第 \(i\) 层只有 \(S\) 中的节点经过了,最终能否满流(即流量为 \(|S|\))。
考虑最小割。对于 \(T \subseteq S\),先删掉 \(T\) 花费 \(|S| - |S / T|\) 的代价。接着要割掉的是 \(N(S/T) \to N\) 的最小割(也就是最大流),即 \(\text{max_flow} + |S| - |S/T| \ge |S|\)。所以对与每个 \(T \subseteq S\),有 \(|T| \le \text{max_flow}\),也就是能在 \(N(T)\) 中找到一个集合 \(T_0 \subseteq N(T)\) 使得 \(f_{i+1,T_0}=1\)。
这个条件是充要的,因此可以 \(O(k 2^k n)\) 处理(做几遍高维前缀和就行)。
而统计 \(\sum_{l<r} f(l,r)\),可以扩展这个想法——容易发现,设 \(f_{l,r,S}\) 为 \(l \to r\) 时 \(|S|\) 是否满流,则 \(f_{l,r,S}\) 关于 \(r\) 具有单调性,可以把 \(r\) 这一位从状态扔进值里面,复杂度 \(O(k^2 2^k n)\)。
83. QOJ8086 Cloyster
太好了是交互题。
我先随便写了个随机化:在矩形里面随机撒 \(B\) 个点,最大值的期望排名是 \(\frac{B}{B+1} n^2\)。从最大值不断往更大的地方走,期望走 \(\frac{n^2}{B+1}\) 次。而每一次期望需要 \(4\) 次询问,因此可以做到 \(4\frac{n^2}{B+1}+ B \approx 4 n\),卡了卡常也过不去,哎。
这种最优解是 \(3n\),看起来应该是一个等比数列求和,因此考虑分治。那么这种网格图应该是横纵交错分治,我们需要将一个网格砍成一半。
首先,选出较长边的中点,并且用平行于短边的直线将长边砍一半。找到短边的最大值,并且询问最大值的邻域。
如果最大值的邻域所有元素都比他小,那么我们找到了整个矩形的最大值。
否则,我们在分治的过程中归纳得到:当前访问位置的最大值,必定在目标矩形中。并且当前访问位置到最终最大值的路径完全包含在当前矩形中,且并不会穿过我们找出的中线。(这个最大值非常关键,如果并不是最大值不能保证“路径完全包含在当前矩形中”,那么就不能通过“不穿过中线”这件事情得出同侧。)
所以,当前最大值与实际最大值应该在中线的同一侧。这样你使用 \(\frac{3}{2} n+O(1)\) 次询问使 \(n\) 砍半,总的询问次数为 \(3n + O(\log n)\)。
84. QOJ8184 Different Summands Counting
如何让每一种颜色出现一次?容易发现,\(\sum_{i=1}^v (-1)^{i-1} \binom{v}{i} = [v > 0]\),所以容斥。
钦定 \(c\) 个位置 \(=v\) 的方案数是(\(c \neq m\))\(\dbinom{n-cv-1}{m-c-1}\)。所以你需要对 \(\sum_{i=1}^n \dbinom{ai+b}{m}\) 进行计算。
容易发现,这玩意关于 \(n\) 是一个 \(m+1\) 次多项式,直接插值就行。我觉得应该可以优化到 \(O(m^2)\)?不太清楚(插值看起来可以优化,因为你选取的点是连续的)。
86. QOJ8190 Jaw-Dropping Set
每个正整数都可以写成 \(2^{\alpha}(2k+1)\) 的形式。显然 \(k\) 相同的数只会选一个。
注意 \(k\) 不同的数之间有整除关系,则 \((2k_1+1)\) 与 \((2k_2+1)\) 差的倍数至少 \(3\) 倍,那么他们对应的 \(\alpha_{\max}\) 肯定差了至少 \(1\)。这样,一定可以通过选取 \(2^{\alpha_{\max}}(2k+1)\) 来做到 \(\lceil \frac{n}{2} \rceil\),这显然是最大值了。
但是显然不需要取 \(\alpha_{\max}\),只需要令 \(\alpha\) 为最大的使得 \(3^{\alpha}(2k+1) \le n\) 的 \(\alpha\) 即可,复杂度 \(O(\log n)\)。
88. QOJ8564 Three Vectors
显然 2-SAT 解计数是极其困难的,所以本题构造出来的关系应该只有 \(O(1)\) 个向量能够满足。
如果 \(a_{1,i}=a_{2,i}=a_{3,i}\),很容易通过限制使得 \(a_{i} = a_{1,i}\)。
其他情况下,都可以找到唯一的 \(1 \le j_i \le 3\) 使得 \(j_i\) 行是特殊的。对于同一个 \(j_i\),我们可以施加限制;对于不同的 \(j_i\),可以模仿样例 2 施加限制。
这样构造出来的关系至多 \(4\) 个向量能满足。也容易证明不可能恰好构造出 \(3\) 个向量。
99. QOJ10542 Protecting Kingdom
用人话说就是,一棵树有边权,部分点是关键点。问长度 \(\le w\) 的链最多能覆盖多少个关键带你。
点分治容易做到 \(O(n \log^2 n)\),长链剖分 + 二分容易做到 \(O(n \log n)\)。
然而,扫码的追忆还在攻击我——长链剖分的时候使用“尝试增量”而非二分可以变为 \(O(n)\),代码甚至会比二分好写。
100. QOJ10543 Square Stamping
直接贪心,搜索一下发现过了。据说状态数为 \(O(n)\)。
101. QOJ10545 String Rank
CodeGolf 邻域大神
#include<bits/stdc++.h>
using namespace std;int r,i,t,m[30];string S;int main(){cin>>S,i=S.size()-1;for(;~i;){for(t=0;26-t;)m[t++]=min(m[t],m[S[i]-97]+1);r=max(r,++m[S[i--]-97]);}cout<<r;}
倒着对整个串建立子序列自动机,贪心地让子序列最靠后。显然答案是初状态到每个点的最短距离的最大值。发现每个点的入边是一段区间,容易优化(即不需要显示建图)。
104. QOJ10697 Judge Error
结论:如果一张图(无自环,但是可以由重边)是边双连通的,那么不可能存在恰一组完美匹配。
证明:设 \(G\) 为一张边数最小的、存在恰一组完美匹配的图。记 \(E_1\) 为完美匹配中的边,\(E_2\) 为其他边。由于每个点在 \(E_1 \cup E_2\) 中至少有两条邻边,则容易证明 \(|E_2| \ge |E_1|\)。当 \(|E_2|=|E_1|\) 时显然是偶环,易证矛盾,设 \(|E_2| > |E_1|\)。容易证明(忘记为啥了),可以从 \(E_2\) 中找到两条边使得他们切边等价,构成一个割集。集训队作业中给的证明实际上不完善——没有证明这两条切边是重边的情况(不过这是极其容易的)。想法就是:利用这个割集划分为两个点集,点击的边数更小所以一定存在两组以上完美匹配,分析完美匹配的形态即得。
回到原题。我们发现,割边是否在完美匹配中是容易得——如果割边分出来的两个点集大小为奇数,它一定在完美匹配中;否则,如果选了这条边一定会出现大小为奇数的分量,坠机。所以只需要快速找割边。
直接弄要遍历 \(O(n)\) 次,而大多数边都是没用的,用异或哈希 + bitset 优化容易做到 \(O(\frac{n^3}{w})\)。
114. QOJ12212 Best Subsequence
和 11 题一模一样。

浙公网安备 33010602011771号