又一做题记录
07.09
CF1874E Jellyfish and Hack
你考虑关心值域序列,那么每次选出的都是一个连续区间,然后挑出其中下标最小的划分,这样区间都是连续的。
考虑一个暴力的区间 DP,设计 \(f(l,r,v)\) 表示值域区间 \(V[l:r]\) 产生的价值为 \(v\) 的下标分配方案数,转移为:
中间那个二项式系数是因为要把两个值域区间的下标值合并起来,然后 \(k\) 这一位放最前面。
你发现长度相等的区间本质相同。于是可以写作:
如果将 \(f(l)\) 视作多项式的话次数是 \(O(n^2)\) 的。直接拉插做在 \(O(n^6)\),虽然很跑不满但是显然过不去。
注意到是卷积形式,考虑生成函数,设 \(F(l)=\sum_{i}f(l,i)x^i\),那么转移就是:
你注意到 \(F(l)\) 的次数仍是 \(O(n^2)\) 的。很有趣的是你可以直接代 \(n^2\) 个数进去得到其点值表示法,然后单次乘法就是 \(O(n^2)\) 的了。
最后你插回系数表示法即可得到 \(f(n)\) 的点值表示法就做完了。复杂度 \(O(n^4)\)。
07.11
P10653 [ROI 2017] 存储器 (Day 2)
首先若 \(t\) 分界位置不为 \(s\) 子集必然不行。
你考虑按 \(t\) 分界划分为若干子任务处理。问题转化为要将一个区间合并成一个颜色。注意判定过程中区间交界处的片段不可被操作否则会连接两个区间。
长度更大的可以合并长度更小的,则选非目标色进行操作不优,那么直接链表 \(O(n)\) 模拟即可。
P13252 [GCJ 2014 #1B] The Bored Traveling Salesman
条件可以描述为一棵生成有根树。要求相当于最小化字典序。
那难道不是直接一次 BFS 就好了吗?考虑如果一个点存在子树与外界断连,那么它就必须把那个子树走完再回退。
我们需要得知回退之后下一步会到哪一个点来确认是否要回退。你发现 \(n\) 足够小所以你可以直接一路回退模拟一遍直接找到可行的最小点。这部分复杂度 \(O(n^2)\)。
然后你发现判断连貌似也有些繁琐,然而 \(n\) 足够小所以每次从头搜一遍即可,题解里声称搜索一遍是 \(O(n)\) 的不懂,反正 \(O(n^4)\) 的复杂度也是可以接受的。
P3626 [APIO2009] 会议中心
若干线段,选出尽可能多的不交线段,在所有可行方案中输出线段编号集合字典序最小的。
忽略字典序要求的话是一个经典问题,每次选可行的右端点最小的线段即可。
一个思路是从小到大贪心,每次判定选当前线段后能否仍能达到最大值。
选一个线段相当于将其所在区间分为两部分,如果能直接得到区间价值的话就很好。你发现原问题的贪心策略是容易倍增的,故而区间价值可以单次 \(O(\log n)\) 求。用 map 之类的维护一下连续段即可。
P6908 [ICPC 2015 WF] Evolution in Parallel
首先如果存在串不是主串的子串显然无解。然后就是要将所有给定模式串分成两条子串关系偏序链。
显然首先按串长排序。考虑子串判定应该只能 \(O(n)\),没有优化空间。
一个暴力就是 \(f(i,j)\) 表示两序列结尾为 \(i,j\) 是否可行,转移只需要考虑下一个串放哪个序列即可,\(O(n^3)\)。
钦定 \(i>j\),那么若存在 \(s_{k}\not\sub s_i\),则 \(f(i,j<k)=0\)。同时,若 \(f(i,j)=1\),则 \([j+1,i]\) 成链。
所以你发现真正有用的只有最小的满足 \(f(i,j)=1\) 的 \(j\) 以及首个包含 \(j\) 的 \(k\)(若存在),对每个 \(i\) 维护 \(g(i)=j,h(i)=k\) 即可,若 \(s_i\sub s_{i+1}\) 则 \(g(i+1)\gets g(i)\),否则合法仅当 \(s_{g(i)}\sub s_{i+1}\lor s_{h(i)-1}\sub s_{i+1}\) 此时 \(g(i+1)\gets i\),否则不合法。
P13385 [GCJ 2011 Finals] Ace in the Hole
神秘困难构造题,都怎么做出来的。
考虑按时间构造。只需保证任意时刻无法确定任何位置必然不为 \(1\) 即可。
如果之后还有未知数,设当前是第 \(k\) 个未知位置,那么为了让最后一个空位也可能为 \(1\),当前位置上的数只能为第 \(k+1\) 小的未知数,如果大了后面必然有另一个比它小的数,如果小了必然有一个比它大的数在它前面。
那如果之后没有未知数了呢。
我们姑且忽略已知数,视作一个 \(1\sim n\) 的未知序列,第一次查了位置 \(n\)。
首先不可返回 \(<n-1\) 的数。对 \(n\le 3\) 显然成立,否则由上文,你此后查位置 \(k<n-1\) 的结果都是一定的(只要不查位置 \(n-1\)),考虑查得只剩下 \(n-1\) 和 \(n-3\),此时 \(n-2\) 位置上的值必然为 \(n\),两个未知数分别为 \(1\) 和 \(n-1\),那么 \(n-1\) 位置上不可能是 \(n-1\),故而答案提前确定,不合法。
在此情境下可以任意返回 \(n-1\)。然而带回原情景,假如此前已知了第二大未知数 \(y\) 与第一大未知数 \(x\) 之间的数 \(z\),这个位置就只能填 \(x\)。考虑反证,若 \(z\) 之前仍有未知数,则其必然不为 \(x\);否则,\(z\) 及之前的所有数形成 \(2\sim z+1\) 的顺序排列,第二大未知数只能是 \(1\),不得返回。
最后只需证明没有这一情况时必然可以填次大未知数。首先只剩两个空的情况肯定要特判一下。否则,你考虑按上述策略生成的当前位置之后的已知后缀,其值域要么连续,要么只有一个数空了出来,你在这里填入次大未知数相当于把那个数继续留下,显然不会形成非法情况。
题目保证存在合法情况,所以证完必要性就不证充分性了。
按上述策略模拟能填次大值就填否则填最大值即可。由上文知填次大值实际上就是把更大那个空往前挪,显然最大化字典序。
ABC466F Many Mod Calculation
你考虑最后再把 \(0\) 去掉。容易只保留降序的 \(a\)。那么对一个数 \(x\),你考虑找到首个小于 \(x\) 的 \(a\),将 \([0,x]\) 划分成长 \(a\) 的若干整段和最后一个余段,前面整段的答案是一样的,直接代一个做子问题乘上段长即可,然后再把余段的贡献加上。
这个东西可以直接记搜,由连续取模的经典结论知子问题个数是 \(n\log V\) 的。最后复杂度两只 \(\log\)。
赛时少打了一个 a[],气笑了。
07.12
ARC086E Smuggling Marbles
你考虑对每个点的弹珠计算它被放入箱子的方案数。也就是说,它要能到达根节点的父亲。发现你只需关心与其同深度的所有点。
一个暴力是 \(f(x,h)\) 表示子树 \(x\) 内深度为 \(h\) 的点可以走出子树的放法数。转移的话枚举那个点来自的子树,剩下的子树全都走不出来。
对每个深度拉一个虚树出来就做完了。也可以长剖做。
P11847 [USACO25FEB] True or False Test P
你考虑 E 必然会操作 \(a_i+b_i\) 最大的 \(k\) 个数。故而答案实际上就是选中的 \(a\) 之和减去 \(a+b\) 最大的 \(k\) 个值。
不妨先按 \(a+b\) 排序,然后钦定一个分界,在分界后选 \(k\) 个 \(b\) 最小的,然后把分界前所有 \(a\) 都选上。对于一个 \(k\),容易倒着扫描线维护优先队列。
现在要对所有 \(k\) 计算答案,后缀信息容易主席树维护。你发现 \(k\) 增大分界不右移,决策单调性直接分治即可。复杂度 \(O(n\log^2n)\)。
QOJ12118 Dendrology
你考虑对每条边计算其被几个生成树所包含。只需同时满足子树内与子树外均存在点即可。不妨容斥,求只包含子树内或子树外的区间数。
你对 \(p\) 维护连续段,单次加点容易直接得到贡献。dsu on tree 即可。
考虑修改操作。你发现只会影响这条边的答案,相当于其序列上两次翻转。
但不可能把所有边的序列存下来。你发现不同边的修改互不影响,所以你可以直接把修改在 dsu on tree 过程中处理,做一个时间轴差分即可。
P6009 [USACO20JAN] Non-Decreasing Subsequences P
注意到 \(k\) 异常小。设计 \(f(i,j)\) 表示考虑到 \(i\),上一个数是 \(j\) 的选数方案数。转移就是 \(f(i,a_i)\gets \sum_{j\le a_i}f(i-1,j)\),其余维度继承。
考虑区间查询呢。你发现倒着做也是容易的,把两段序列进行一个拼接也是容易的,所以直接挂上猫树即可。
但是空间爆了。把询问离线下来即可。
P3251 [JLOI2012] 时间流逝
状态与元素序列成双射,转移成树状。
超过阈值的集合均不能往回走且为叶子,其余都是双向边。集合总个数实际上是不多的,跑一下大致在 \(10^6\)。
设计 \(f(x)\) 表示到达点 \(x\) 的期望天数,你发现叶子很不好处理,考虑转而设计为从 \(x\) 到达叶子的期望天数。
直接高消显然爆了。对于这类树上消元问题,一个技巧是将 \(f(x)\) 表示为关于 \(f(fa_x)\) 的一个一次函数 \(kf(fa_x)+b\),到根节点时就有 \(f=b\),然后如果需要依次往下代入即可。
我们记 \(sk_x=\sum_{y\in son(x)}k_y,sb_x=\sum_{y\in son(x)}b_y\),移项得到:
就做完了。注意根节点时特殊有 \(P=0\)。
CF1096E The Top Scorer
首先总方案数可以一个组合数搞定。
获胜方案数呢?类似地,枚举 \(r\)(后文 \(r\) 均指钦定 \(a_1=r\)),然后再枚举有 \(p-k\) 个 \(r\),考虑求剩下的 \(k\) 个任意分配值全都小于 \(r\) 的方案数。
考虑生成函数。
复杂度 \(O(sp^2)\)。
07.13
P11534 [NOISG 2023 Finals] Inspections
注意到每次相当于给一段区间赋值为一个等差数列状物,考虑到各点是独立的,我们不妨使用这条斜线段的纵截距统一描述整段的时间,这样一次操作就相当于一次区间覆盖,直接颜色段均摊,对答案维护一个后缀差分数组即可。
P11535 [NOISG 2023 Finals] Airplane
注意到答案显然形如一段上升和一段下降。我们先考虑上升段。
显然高度尽量高不劣,因此我们每一秒都上升高度,这样一个点的距离即为到达该点时的高度,然后容易模拟题意跑一遍最短路,记本次得到的距离信息为 \(f\)。同理从 \(n\) 开始跑一遍,得到距离数组 \(g\)。
我们考虑在路径最大值处更新答案,点 \(x\) 的贡献为 \(2\max(f(x),g(x))\)。但这样不一定是优秀的,因为你在一侧额外多往上飞之后,会在另一侧产生额外的下降代价。所以我们还要考虑一段平飞段。
然后一个关键性质是平飞段性质小于 \(2\),否则可以转化为一个上升和一个下降。所以只需要再枚举有向边即可,\((u,v)\) 的贡献为 \(2\max(f(u),g(v))+1\)。
P11536 [NOISG 2023 Finals] Curtains
考虑扫描线,每次加入以当前 \(r\) 为右端点的线段,对每个 \(l\) 维护从它能连续到达的最远距离,初始设为 \(l-1\)。
修改形如对一段区间内,原来值在 \([l,r]\) 之间的数全部改为 \(r\)。我们考虑对这个东西打标记 \((l,r)\)。考虑合并标记,首先新的 \(r'\) 肯定比原来的 \(r\) 大,假如 \(l'\le l\) 就可以直接把原来的 tag 删了,否则假如 \(r\in[l',r']\) 就可以合并成标记 \((l,r')\),但你发现剩下的情况不好做。
注意到你只需要单点查询,并且无法合并的 tag 形如值域上的不交区间,所以考虑标记永久化,对每个点存一个标记栈维护这些区间,查的时候一路回溯,用返回值在标记栈内二分找到包含它的区间并更新其信息即可。复杂度两只 \(\log\)。
优化:注意到无法合并你就可以直接不管新的 tag 了,因为原来打了 tag 的地方里面所有值都是不超过原来 tag 的 \(r\) 的。所以可以做到一只 \(\log\)。还有一种思路是扫描线对每个点维护能包含它的最大左端点,查询只要区间 \(\min\) 不小于给定左边界即可,也是一只 \(\log\)。
P6235 [eJOI 2019] 矩形染色
黑白染色后黑白是独立的。只考虑一种颜色。
你发现可以描述为,如果一个第一类对角线不选,其对应的所有第二类对角线都要选。一个关键性质是,其对应的是一个连续区间。
故而我们可以直接转化成序列线段问题,选一些点,一个区间产生贡献仅当其内所有点都被选,最大化区间贡献和减点权和。容易写一个平凡的 DP 然后扫描线优化即可。
P9985 [USACO23DEC] Train Scheduling P
最后的调度方案可以描述为若干时间段 \([l,r]\) 交错表示左向和右向列车此刻行驶。满足 \(l_{i+1}=r_i+T\)。列车 \(i\) 产生的代价为首个 \(l\ge i\) 的同色段 \(l-t_i\)。
易知有效的时间段划分方案满足,每个段右端点必然为其颜色某个 \(t_i\) 加上若干个 \(T\)。为某个 \(t_i\) 是因为通常情况下如果右端点超出去了那往回挪到这个 \(t_i\) 不劣,加若干个 \(T\) 是因为可能上一个段太近挪不回来所以表现为上一个段末尾加 \(T\)。
考虑摈弃时间轴,维护两个站的列车序列,分别将 \(t\) 按序记为 \(a,b\) 两数组。
考虑一个 DP \(f(i,j,0/1)\) 表示现在已经送出了 \(a\) 站前 \(i\) 车与 \(b\) 站前 \(j\) 车,当前是 \(a/b\) 站出发段,仍需多少时间。转移是容易的,以 \(a\) 为例,不结束段有 \(f(i,j,0)\gets f(i+1,j,0)\),结束本段,若 \(b_{j+1}\ge a_i+T\) 则直接 \(f(i,j,0)\gets f(i,j+1,1)\)。
但若 \(b_{j+1}<a_i+T\) 我们就需要考虑直接加 \(T\) 的方案,这一步直接模拟,显然加 \(T\) 次数不超过 \(n\) 因为每次加都说明对方有点被包含其中。这样单次转移就达到了 \(O(n)\),复杂度 \(O(n^3)\)。
考虑优化,你发现对于一个点 \(i\),它的跳 \(T\) 过程是一定的,故而你可以只跑一遍最后一个合法的 \(b_k<a_i+T\) 的 \(k\),往前依次增添贡献即可。复杂度 \(O(n^2)\)。
gym103371I Organizing Colored Sheets
显然只需要对每个 \(h\) 维护最大的可行 \(w\) 即可。你考虑一个大小可行如何判定。
因为可重所以显然任意能铺就铺。考虑对于每个点判定,假如所有包含它的放法都不合法,那就铺不满。然而这个判定并不很有建设性。
注意到,只需要所有挨着边界与障碍的点均可被包含,则该尺寸合法。
枚举四个方向,你对每个点预处理当前方向意义下其上下最近障碍,然后横着顶到头也要更新一下,最后合并得到的信息计数即可。整合信息直接对非法情况二维前缀和即可。
07.14
QOJ3687 Boss 单挑战
你发现回血、普攻、法攻是独立的。换句话说,只要长度一定,普攻和法攻产生的攻击是一定的,与其在原序列上的位置无关。所以你可以先 \(O(n^2)\) 暴力 DP 出普攻和法攻各长度的贡献然后卷起来。
那么只需要考虑最小化回血即可。我们从前往后枚举回合,如果当前空位足够结束游戏就输出,否则我们需要保证剩余血量超过 \(a_i\),显然之前设定的回血回合全部保留,你从后往前将空位设定为回血回合,对每个位置维护从开头到这里时剩余的血量,最大血量与之的差的后缀 \(\min\) 就是在某一个回合额外加血能对回合 \(i\) 时的血量产生的贡献。
P4074 [WC2013] 糖果公园
树上带修莫队板子。
P10070 [CCO 2023] Travelling Trader
\(K=1\) 是简单的,树形 DP 找一条链即可。
\(K=3\) 你发现必然有解做完全部,搜一遍奇数层做完再往下偶数层回溯前再做即可。
\(K=2\) 考虑树形 DP。你设计 \(f(x,0/1)\) 表示 \(x\) 子树回到 \(x\) 父节点,需要先操作 \(x\) 或者回溯前再操作 \(x\) 的最大价值。\(g(x,0/1)\) 则表示 \(x\) 子树不考虑回到父亲,\(x\) 是否需要最先操作的最大价值。
一共有七种转移,维护一些信息的最大值、次大值、第三大值即可做到 \(O(n)\) DP。输出方案只需记录一下转移过程然后按转移思路模拟即可。
P11369 [Ynoi2024] 弥留之国的爱丽丝
由追忆知有向图连通性只能 bitset 实现。
考虑操作分块。
你一个块内只会关系到 \(O(B)\) 个点和边,不妨先忽视这些边缩点,你发现只需要维护每个点到这些关键点的可达性,单次重构即可做到 \(O(n+m+\frac{(n+m)B}{w})\)。
查询就不断加入当前黑色的关键边,每条 \((x,y)\) 形如 \(u\to x\) 就将 \(y\) 的可达点集或予 \(u\),这样每条边只会在其 \(u\) 加入的时刻贡献一次,单次询问 \(O(\frac{B^2}{w})\)。
故而复杂度为 \(O(\frac{(n+m)q}{w}+\frac{(n+m)q}{B}+\frac{B^2q}{w})\)。取 \(B=\sqrt[3]{(n+m)w}\) 即可。
QOJ7603 Mex on DAG
你考虑描述一条 \(\mathrm{mex}> v\) 的路径。也就是其包含 \([0,v]\) 中所有权值的至少一条边。
你考虑判定这样一条路径是否存在。你发现这充要于存在 \([0,v]\) 中每个权值选一个边的选法,使得选出的边两两可达。边的可达性容易预处理。
注意到每个权值只有两条边,因此可以转化成一个 2-sat 问题。二分答案即可。
QOJ914 分身术
你先考虑如何判定一个集合的区间能分配成无交 \(k\) 组。按右端点升序放区间,你发现每次贪心地放入已有区间右端点尽可能大的组即可。
接下来你考虑对一个 \(k\) 求其最优选取集合。你发现直接按右端点升序枚举区间,按上述贪心策略能放就放即可。你发现你大可不在意具体放入哪个区间,因为能放相当于区间最大覆盖数量不超过 \(k\),只需维护区间最大覆盖数即可。
你考虑如何快速处理该过程。考虑按 \(k\) 升序计算答案,每次找到最远的最大覆盖次数恰为 \(k\) 的位置,然后找到其右侧最小的 \(r\) 对应区间将之加入。显然一共只会找 \(O(n)\) 次,用线段树维护即可,\(O(n\log n)\)。
07.15
QOJ5507 Investors
你注意到每次给一个后缀加不劣。那你每次都加一个足够大的值抹平两段间的所有逆序对不劣。
所以现在就是要选出 \(k\) 个分界点,最大化经过这 \(k\) 个点的线段数。设 \(f(i,j)\) 表示前缀 \(i\) 选了 \(j\) 个点钦定选 \(i\) 的方案,线段贡献在其右端点处计算。
你发现这个东西是有决策单调性的,\(i\) 增大最优的 \(j\) 不可能减小。最右边那个如果离线扫描线的话就做成了区间覆盖,你直接扫一遍预处理出所有 \(n^2\) 组 \(i,j\) 的答案即可。复杂度一只 \(\log\)。
实际上有简单的多的做法,你直接对没覆盖点的线段数 DP,你发现每次只需要求区间逆序对数就可以了,然后决策单调性一只 \(\log\)。
QOJ5367 递增树列
你发现,lca 序列形如从根开始到某个叶子的一条链,当 lca 变化时,原 lca 子树内其他点必须已经全部添加进序列。故而容易考虑设计 DP \(f(i,j)\) 表示子树 \(i\) 中有 \(j\) 个点是在 lca 在子树内时贡献的,也就是剩下的 \(i-j\) 个点都在祖先时被使用了。
考虑转移,枚举下一个 lca 所在子树 \(y\),你要解决的就是将若干个各有一定数量的小球种类排成一排方案数,使得两两相邻不同色。可以对这个直接容斥,也可以维护 \(g(i,j)\) 表示序列中现在有 \(i\) 个不同色邻对和 \(j\) 个同色非法邻对的方案数,两者显然都是逐个考虑剩下子树合并信息。
理论上可以做到 \(O(n^4)\),但我也不知道我最后那一坨挺快的代码复杂度是多少。
P6684 [BalticOI 2020] 小丑 (Day1)
你考虑有无奇环如何表示。你发现无奇环等价于为二分图,即可以黑白染色。
考虑维护题目询问。考虑对每个 \(l\) 维护最小的 \(r\) 满足只考虑 \([l,r]\) 内的边,存在奇环。原询问你考虑将序列倍长就变成保留连续区间。
你发现 \(r\) 关于 \(l\) 单调递增。考虑整体二分,可撤销并查集维护黑白染色即可。
07.16
[NOIP2026 模拟 R2] 友谊赛
你考虑每次选祖先中尚未确定的点最多的赋最大值即可,贪心策略容易调整法证明。
考虑实现,你拿一个线段树维护所有叶子的上述信息,实际上就是叶子深度减去最近的已确定祖先的深度,线段树维护区间加,每个点只会修改一次所以可以暴力跳,每次修改只有一个子树已经有值所以两次区间加即可。
[NOIP2026 模拟 R2] 数数 / QOJ5530 No Zero-Sum Subsegment
你考虑判定一个序列是否合法,维护前缀和,只需判定前缀和中有无重复元素即可。
考虑计数,对前缀和折线计数,有若干次 \(-2,-1,+1,+2\) 走法,要求不能走到重复点。经过手摸发现,倘若我们要求终点在零之上(在零之下是对称的可以互换 \(a,d,b,c\) 直接做),那么最终形态形如开头一段向下的谷,中间一段上升,和最后一段向上的谷。
开头的谷形如,先向下走若干个 \(-2\),然后走一个 \(+1/-1\),然后向上走 \(+2\) 走回 \(1\) 的位置。末尾的谷是类似的,为了防止与中间的上升部分算重,不妨钦定最终结束的位置必须为谷开始位置加一。注意特判没有谷的情况,可能一个 \(-1\),或者直接进入上升部分或结束。
上升段三种走法,\(+1\),\(+2\),\(+2-1+2\),你需要将 \(-2\) 在谷中消耗完,所需的元素一定,这三种走法个数也一定,直接一个可重集排列即可。
[NOIP2026 模拟 R2] 跳棋 / QOJ1811 How to Move the Beans
考虑 SG 函数。你发现 SG 函数值不超过 \(3\)。所以直接 DP 即可。有 # 的行是好做的。没有 # 的行你发现每个点至多走回到自己后面一位,考虑将序列拆成前后缀分别 DP 然后拼合起来,比较平凡。
[NOIP2026 模拟 R2] 波动 / P8476 「GLR-R3」惊蛰
首先显然有用的值只有给定的 \(a\) 否则不优,容易有一个 \(O(n^2)\) DP。
考虑优化,直接放到线段树上,你要动态维护后缀 \(\min\)、区间加、区间加各自离散化后的值。第二者是最好做的,对于第三者,你打一个标记,因为两个序列都是单增的,所以新的最大值只需加上右端点离散化前的值即可。
考虑维护后缀 \(\min\),你发现现在相当于是按 \(a_i\) 划分成了左右两个单增序列,在左边线段树上二分找到首个比 \(a_i\) 位置值大的然后区间推平即可。
QOJ8109 Postcards / Przesył
如果不强制在线,考虑操作分块,每块把相关的边都去掉跑一遍并查集,只会有 \(O(B)\) 个块与它们之间的连边,对每个询问跑 tarjan 即可。
但是强制在线了。你发现 \(r\) 很小,考虑做与 \(r\) 有关的复杂度。你发现可以拉出一棵 dfs 生成树,你删完至多 \(r\) 条被修改的树上边之后,dfn 序列会被划分为 \(O(r)\) 个区间,每个区间内部都是连通的。考虑判定区间间连通性,你发现区间间连边数是易得的,那么容易得到每对区间的连边关系,跑一遍 tarjan 即可。
[hidden] JPC
你考虑对一个树的形态求 \(p\) 的个数。只有 \(n\) 对大小限制,并且不成环。你定义 \(f(i,j)\) 表示子树 \(i\) 中有 \(j\) 个点排在 \(i\) 前面的方案数。那么合并是容易的,可以枚举 \(u\) 插入的位置,前缀和优化,复杂度树上背包 \(O(n^2)\)。
你考虑对一个树的形态高效地计算其权值。考虑组合意义,就是从每个点的连通子树中选一个点贡献权值,贡献为乘积。你可以对每个点钦定它贡献给了 \(j\) 个祖先。然后转移应该是容易的。所以再开一维钦定点数跑 DP 就做完了。\(O(n^4)\)。
07.17
P9262 [PA 2022] Łamigłówka
两次有效操作之后就会到一个角上。然后接下来就是在四个角上挪动。
你发现任意时刻在四个角上图形的形状是不变的,只是旋转后一个块可能不在原来的位置。被增预处理出某个位置在某个角上转几次后到达的新位置即可。
QOJ7012 Rikka with An Unnamed Temple
权重模 \(k\) 为 \(t\) 想不到什么好的处理方法,考虑直接加一维状态。
现在要求所有禁行点的方案。你考虑拿总方案减去经过了禁行点的方案。从 \(1,n\) 各跑一遍即可。但这样是错的,因为假如所有最优路径都经过了当前点那么答案的最大值变化了。
考虑所有不经过 \(x\) 的路径必然存在唯一一条边从拓扑序比 \(x\) 小的指向拓扑序比 \(x\) 大的,枚举边区间加即可。注意处理 \(1\) 走不到的和走不到 \(n\) 的点。
QOJ6538 Lonely King
你注意到你的操作形如对一个根,枚举它所有仍连通的子树,从每一个里面选一个叶子将它们间的路径删了缩成一边,不劣。
一个暴力是定义 \(f(x,i)\) 表示子树 \(x\) 预留点 \(i\) 给其祖先,转移相当于对每个点枚举了其子树内所有叶子,复杂度 \(O(n^2)\)。
考虑转移 \(x\) 时,除了其选定的叶子,其余子树的贡献形式为 \(\min_i f(y,i)+C_xC_i\),容易考虑李超线段树维护,过程中只需额外支持全局加和线段树合并即可。
P9260 [PA 2022] Miny
只能考虑将所有引爆关系连边跑可达性统计。考虑点分治,块内距离定义为到根距离和,显然算重不用管,\(d_i+d_j\le r_i\iff d_j\le r_i-d_i\),直接前缀优化建图,最后可达性上 bitset 发现空间有点爆,分个块每次只跑块内点即可。
07.18
QOJ14310 Moving on the Plane
考虑转切比雪夫距离分离两维,那么现在就是要求所有点都在一个正着的矩形内,显然你只需关心其左边界和下边界,枚举编号最小的在边界上的点,然后枚举所有点求一下方案数即可,前缀和优化做到 \(O(nm)\)。
QOJ16332 Efficient Express
首先大可忽略所有 \(\exists j,\forall a_i=c,p_j\ge i\land x_j\le i\) 的 \(c\)。显然对每个颜色 \(i\) 你只关心其最左边和最右边的点能否连通,记作 \(l_i,r_i\)。那么每个 \(i\) 都需要存在一个 \(j\) 满足:
那么 \(l_j> l_i\land j>i\) 的 \(j\) 就可以忽略了。考虑视作点 \((p_j,x_j)\) 和 \((l_i,i)\) 拍到坐标系上会直观一些。
考虑容斥求不合法方案数。你考虑去枚举最小的不合法的 \(i\) 记作 \(t\),则需要保证所有 \(<t\) 的均合法,考虑容斥。
存在一个性质是,只关心 \(x_j\le i\land y_j>i\) 这一不合法条件,你发现 \(i\) 越大越严苛。因此对于比一个不合法点小的点,其这一判定必然不合法,其合法性判定只需关心 \(p_j<l_i\) 的点。
故设 \(f(i)\) 为钦定 \(i\) 为最小的不合法点的带系数方案数,转移枚举之前钦定的位置,\(f(t)\) 直接把所有相关点都钦定掉,对每个比 \(t\) 小的 \(i\):
\(t\) 的贡献即为:
QOJ9798 Safety First
萌萌根号分治。见这里。
P12486 [集训队互测 2024] 木桶效应
考虑组合意义。一个排列组的价值等价于给每一列赋一个权值 \(val\) 满足 \(val_i\le p_{j,i}\) 的方案数。
先考虑 \(q=0\) 的情况。
考虑对一个 \(val\) 序列求 \(p\) 方案数,你升序枚举 \(i\),然后对每行确定填入 \(i\) 的位置,只需知道有 \(j\) 列的 \(val\le i\) 即可得方案数为 \((j-i+1)^m\)。容易设计 \(f(i,j)\) 表示考虑到 \(i\) 有 \(j\) 列 \(val\le i\) 的方案数。
考虑 \(q\ne 0\) 的情况。
你注意到 \(q\) 足够小。考虑状压存在钦定点的列,每次转移都将存在钦定点的行列与其他行列分开考虑。设计 \(f(i,j,S)\) 表示考虑到 \(i\) 有 \(j\) 无钦定列 \(val\le i\) 且 \(S\) 中的有钦定列 \(val\le i\) 的方案数,先不考虑 \(i\) 的贡献把 \(i-1\) 的信息转移过来,再对各个状态计算本 \(i\) 中各行的选法贡献即可。
有钦定列转移需要枚举 \(S\) 子集,处理完无钦定列转移后跑一遍高维前缀和即可。对各个有钦定行你对每个 \(S\) 维护其在 \(S\) 中且值比当前 \(i\) 大的列数,转移的时候其系数即为无钦定行系数减去该值,跳过已经钦定了 \(i\) 的行。复杂度 \(O(n^22^q(n+q))\)。
07.19
[hidden] 重置
你注意到 \(val\) 的限制是很强的,只能考虑暴力维护连续段。
考虑前面部分,你发现随区间长度增大 \(\min\) 递减 \(\operatorname{mex}\) 递增,所以可以考虑扫描线然后维护分界点,你注意到这个分界点也是单调右移的。
考虑深挖 \(\operatorname{mex}\) 性质,经典地,极小 \(\operatorname{mex}\) 区间只有 \(O(n)\) 个,找出它们后就可以得到 \(O(n)\) 个扫描线区间覆盖操作维护 \(\operatorname{mex}\)。类似地 \(\min\) 的维护可以单调栈变为 \(O(n)\) 个区间覆盖。
考虑得到上述所有操作后进行扫描线维护分界点,用两个 set 维护分界点前后的连续段,分界点移动就加入单点,区间覆盖只执行分界点一侧的部分即可。考虑区间覆盖作用,相当于给长度在一个范围内的统一增添一个值,同时一个区间若不被操作则 \(r\) 每增 \(1\) 其会给长度自增 \(1\) 并贡献其值,考虑维护每段的出现时间然后在其消失时统一处理这一部分贡献,也是一个区间加值。
那么现在就是若干个区间加点维护连续段,扫描线 set 即可。
07.20
[NOIP2026 模拟 R3] 望月者计划
考虑容斥,用总方案数减去非法方案数。转化为 \(a_0=m\) 后边若干个 \(m-1\) 和 \(-1\),要求 \(i\in[1,m),a_i>0\),不妨枚举首个 \([1,m)\) 中为 \(0\) 的位置。
重点在如何求他前面一直非零的方案数。由 Raney 引理,对于一个和为 \(1\) 的整数序列,其循环位移中只有恰好一种满足前缀均为正数。
回到我们的问题,你考虑把最开始那个 \(m\) 改成 \(m-1\),那么现在总和为 \(-1\),显然等价于总和为 \(1\) 的问题(直接取反),同时合法方案首位必然为 \(m-1\) 可以直接把 \(1\) 加回来,所以直接求循环位移意义下本质不同的方案数即可。
[NOIP2026 模拟 R3] AC 自动机
显然考虑对每个状态存当前长度下在该状态的串数 \(f\)。难点在于失配后要上传到首个有这一字符转移的失配树祖先。转成计数就是,对于转移 \(\delta(x,c)=y\),转移权值为 \(x\) 子树中对 \(c\) 失配后最近的有 \(c\) 转移祖先为 \(x\) 的 \(f\) 和。
考虑容斥,用子树和减去非法元素和,你发现非法元素形如找到若干个最近的有 \(c\) 转移的子孙然后把他们的子树和减掉,你发现可以直接搜一遍动态维护每个值最近的有转移祖先,然后将当前点暴力插入相应的祖先的队列中,转移时枚举队列减去贡献。精细实现可以做到 \(O(nt)\)。
[NOIP2026 模拟 R3] 归源之仪 / QOJ14718 Meeting for Meals
做过可惜没做得及。
显然等价于最小化相遇时间。暴力就是枚举 \(i,j\) 然后枚举相遇位置,你考虑枚举相遇位置所在边,假设 \(i\to u\land j\to v\),那么只需保证相遇后不超时即 \(\min\{dis(i,u)+w+dis(v,1),dis(j,v)+w+dis(u,1)\}\le t_{\max}\) 即可,用时显然为 \(\frac{dis(i,u)+w+dis(j,v)}{2}\)。
考虑优化。你发现对于一定的 \(i,u,v\) 显然找最近的 \(j\) 即可,可以预先跑一遍多源最短路。更进一步,你发现 \(i\) 也只需要找离 \(u\) 最近的那个即可,别的 \(i\) 在 \(u\) 点和最近的 \(i\) 相遇就不劣于在 \((u,v)\) 与 \(j\) 相遇。所以只需要跑最短路然后枚举边即可。
[NOIP2026 模拟 R3] 声骸回响
注意到若 \(>1\) 的元素之和超过了 \(24\) 必然无解。那么只需考虑 \(>1\) 的元素和不超过 \(24\) 的情况。又注意到此时若序列长度超过 \(24\) 那么必然有解,你可以把 \(>1\) 的全部加起来然后选任意个 \(1\) 加上去。
那么只需要考虑序列长度不超过 \(24\) 的情况了,直接每次把路径拉出来跑暴力 DP 即可。
[hidden] 树^{数} + 树^{数} + ...
显然一棵笛卡尔树双射一个序列。考虑求序列贡献。
你发现比一个点大的数量就是走到根右转次数,正常笛卡尔树是维护右链,不妨倒着生成维护左链,那么每次加点只会贡献当前点自己的价值,移到它右子树的点贡献不变,所以只需维护链长即可。
故而直接 \(f(i,j)\) 表示加到 \(i\) 左链长为 \(j\) 的贡献和,前缀和一下即可做到 \(O(n^2)\)。
[hidden] 覆盖
DAG 中一些边能构成一个路径当且仅当两两可达。必要性显然,充分性考虑构造证明,维护一条路径然后加入边,他必然可达一个后缀并被一个前缀可达,插入交界点处即可。
07.21
P5476 [CCO 2015] 挖掘
先不考虑蛋求每个区间的贡献,容易考虑二维前缀和,注意到每个种类的点数足够小,所以直接枚举 \(2^S\) 种选取情况容斥即可。再考虑蛋,只需对每个区间求出其贡献消失的时刻,形如一个二维矩形最小值,扫描线标记永久化挂 set 维护即可。最后再对时间轴扫描线并处理回答,显然权值不超过 \(m\) 放线段树上维护区间和就做完了。
QOJ5363 ZYB 的游览计划
考虑计算一段的价值。经典地,按 dfn 排序后求出两两相邻距离即可。容易发现决策单调性,最优决策点单调右移。考虑分治,段的价值可以莫队 set 维护。
P10544 [THUPC 2024 决赛] 转化
你考虑建图跑一遍缩点,但由于一个点只能选一种转化所以 SCC 内并非单纯的无穷多。可以描述为以下情况:
考虑一个有值的点:若其存在一种转化生成至少两个本 SCC 的点,那么本 SCC 可以到达无穷;若其存在一种转化生成一个本 SCC 的点和若干外界点,则这些外界点及它们的可达点均可到达无穷;剩下的转化只有两种,要么全部连向外界点,要么只有一条边并连向本 SCC 的点。
考虑维护每个 SCC 内的点能否无限生成,额外打一个标记即可,直接按上述规则更新,同时将其所有后继均设作无限,每个点只会被打一次。此外,若不可无限生成,其只会经过“全部连向外界点”的转移,对此建图逆拓扑序 DP 维护 \(f(i,j)\) 表示一个 \(i\) 能生成几个 \(j\),同时动态维护 \(h(x)\) 表示不考虑无限前提下 \(x\) 的生成个数,在一个 SCC 确定后用其 \(f\) 更新所有点的 \(g\) 即可。
P13804 [SWERC 2023] In-order
在先序后序均给定的情况下,容易生成一棵形态一定的二叉树,只有单儿子点其儿子位于父亲左右不确定。容易先找出这些点。那么方案数只在于这些单儿子点。
容易发现,区间内必然存在唯一一个深度最浅的点,其余区间内点必然位于其子树之内。你从这个点往下搜,对于子树中一个单儿子点,只要其点子树中存在区间内的点,这条边方向必然一定,否则方向任意。
对于子树外部分,你只在乎该点到根路径上的单儿子,剩下的没有影响可以任意确定。你发现他们每个只会造成 \(1\) 的影响,也就是父亲这一单点是否放在子树左侧,所以任意在其中选取所需个数个点放左侧即可。
考虑所需点数。记区间内深度最浅的点为 \(x\),你首先得到其祖先中有两个儿子且 \(x\) 位于其右子树的点,它及其左子树必然位于给定区间之前。然后只需考虑 \(x\) 的左子树大小即可,若 \(x\) 有两个儿子则一定,否则若区间长为 \(1\) 它的儿子可以任意放之左右两种情况求和,再否则容易判定其儿子位于其左亦或其右。
QOJ5095 九王唱
倒着做。最后一个人只能把自己更讨厌的那一首删掉。对于倒数第二个人,若后一个人与自己最讨厌的是同一首,就把自己次讨厌的删掉,否则把自己最讨厌的删掉不劣。
依次前推,你发现每个人删掉的元素就是后面的人没选的元素中自己最讨厌的那个。
考虑对所有 \(p\) 求答案。你发现 \(p\) 右移一位,移动点以外的点其选中指针不降,移动点本身指针归零,直接做即可,\(O(n^2)\)。
QOJ3996 Race
注意到特判 \(S=T\) 之后,只要经过所有种类边奇偶性相同即可。首先所在块必须有所有颜色的边。
容易想到赋边权后异或,经典地跑一个 dfs 生成树出来,树边边权即由其种类得到,非树边额外异或上经过的树边异或和,最后把 \(S,T\) 到根的异或和或者其再异或上全集的值丢进线性基即可。
QOJ4001 Barbecue
考虑描述必败局面。先判掉一开始就是个回文串的情况,跑个马拉车即可。否则,你考虑必败当且仅当拿走左端点和拿走右端点均会形成回文串,发现形如 abababab,发现其必然是偶数,发现先后手串长奇偶性一定,所以判掉开局回文后胜负仅由串长奇偶性决定。
07.22
P10806 [CEOI 2024] 洒水器
考虑二分答案。容易考虑到贪心地左边没有就右转,否则左转,但发现这是错的。考虑到可能有一个点右转接一个点左转的情况。
你发现只考虑这三种单位元就可以表示所有合法方案了,设计 \(f(i)\) 表示考虑到第 \(i\) 个洒水器最远能贡献到哪一朵花,要求其前缀必须全都被贡献,转移从上一状态暴力拓展即可,一次 DP 是 \(O(n)\) 的。
P9139 [THUPC 2023 初赛] 喵了个喵 II
考虑如果每个值只有两个元素的话,存在合法划分的充要条件是,将每个值视作其两元素间的一条线段,则线段无交。
回到原问题,每个值有四个元素,巧妙地,考虑将之拆成两个值,规约回上述问题。拆法形如 aabb 和 abab。显然原问题有解充要于存在一组拆法有解。
每个元素有两种拆法,考虑 2-sat,冲突为包含关系,主席树优化建图即可。
QOJ18036 Algorithm Was Applied
考虑令一个点的贡献为 \(n-cnt\) 其中 \(cnt\) 为与其最终相连并在其之后的点数,最终求乘积即可。
考虑如何求 \(cnt\),你发现 \(i\) 最终能走到的点,形如它本来能走到的点,与连向它的在它之前的点能走到的点,的并集。你考虑拿一个 set 直接维护,顺序枚举 \(i\) 并使用并查集把 \(i\) 和连向它的合并起来,可达点集启发式合并即可。
set 总点数是 \(O(m)\) 的,故而复杂度两个 \(\log\)。
07.23
[NOIP2026 模拟 R4] 串串游戏 / QOJ4666 Delete And Win
考虑在 T 上枚举首个比 \(S\) 大的位置 \(i\),在 \(S\) 中匹配 \(T[:i-1]\) 并最小化结束位置 \(x\),找到 \(x\) 后最近的比 \(T_i\) 小的 \(S_j\) 或者 \(j=|S|+1\),那么除了匹配上的位置和 \(S[j:]\) 其余点都必须删,取最小值即可。
[NOIP2026 模拟 R4] 最长上升子序列 / QOJ4629 Longest Increasing Subsequence
相当于是每两个间隔之间都按线段树类方式分层,你可以从第一个点走到最后一个点,要求点的层数不降,求最多能经过的点数。层数只有 \(\log V\),直接定义 \(f(i,j)\) 表示走到点 \(i\) 位于第 \(j\) 层的方案。
考虑一个间隔内建的树,你发现除了最后一层都是满的,直接从对应层开始走即可。每层所有节点大小只会是一个 \(x\) 和 \(x+1\),容易 \(O(\log V)\) 维护每层点数。考虑最后一层,可能从倒数第二层走过来,但实际上倒数第二层按 \(x\) 和是否有 \(x-1\) 只有四种情况,四种都有简单的策略,直接分讨即可。复杂度一个 \(\log\)。
[NOIP2026 模拟 R4] 墙 / QOJ8712 Flooding Wall
定义 \(pre,suf\) 为前后缀最大值,所求即为:
考虑对单点求贡献,最大值的最小值不好处理,你考虑写作 \(pre_i+suf_i-\max\{pre_i,suf_i\}\)。\(h_i\) 项的贡献是好求的,考虑求剩下三项。
先考虑全局 \(\max\),我们枚举 \(\max=x\) 求局面数,直接做是 \(O(n^2)\) 的,你发现你只在乎由 \(a,b\) 与 \(x\) 的关系划分出的 \(6\) 种点有多少个,降序枚举 \(x\) 的话,每个点与 \(x\) 的关系只会变化 \(O(1)\) 次,动态维护即可。
再考虑前后缀 \(\max\) 求和,分开处理,二者本质相同。同样地考虑枚举 \(\max=x\),不妨记与 \(x\) 的关系为小于大于等于的分别为 sbe 类点,那么合法前缀需要满足其中有 e 类点且没有 b 类点。
每次枚举前缀复杂度爆了,你发现 e 类点总数只有 \(n\) 个,考虑对局面求合法前缀数,枚举第一个 e 类点位置 \(i\),再枚举第一个 b 类点位置 \(j\),那么序列分为三段,那么 \(<i\) 的只能取 s,\((i,j)\) 内的只能取 s 或 e,\(>j\) 的可以任意取,贡献易求。你发现容易把 \(j\) 的贡献挂到线段树上然后直接区间求和即可,顺序枚举 e 类点容易处理 \(<i\) 的点只能取 s 的限制。
[NOIP2026 模拟 R4] 有理数 / QOJ1883 Rational Dimasik
不妨先最简化给定分数为 \(\frac{b}{a},\frac{d}{c}\dots\),所求即为 \(\prod\frac{ac}{\gcd(ac,ad-bc)}\),只需考虑如何求分母。
考虑独立处理各质因数 \(p\)。不妨设 \(a=a'p^{k_1},c=c'p^{k_2}\),\(p\not\mid a',c'\),若 \(k_1<k_2\) 则 \(\gcd(ac,ad-bc)=p^{k_1}\gcd(a'c'p^{k_2},a'd-bc'p^{k_2-k_1})\),由于 \(p\not\mid a'd\land p\mid bc'p^{k_2-k_1}\implies a'd\not\equiv bc'p^{k_2-k_1}\pmod p\),故而 \(\gcd\) 中必然不含 \(p\) 因子。我们于是解决了 \(k_1\ne k_2\) 的情况。
考虑 \(k\) 相同时,提出 \(p^k\),原式变为 \(\gcd(a'c'p^k,a'd-bc')\),那么你就是要找到最大的 \(k'\le k\) 使得 \(a'd\equiv bc'\pmod{p^{k'}}\)。可以差分拆 \(\max\),即求 \(\sum_{k'=1}^k\left[\frac{b}{a'}\equiv \frac{d}{c'}\pmod {p^{k'}}\right]\),开个桶即可。
07.24
#7623. 彩带染色
你发现刷子的位置是重要的,同时相对顺序一定具体颜色是可以忽略的,且一组位置唯一确定一列的颜色段情况,故而考虑用刷子位置映射列状态,压位维护每一行是否有刷子。
考虑转移,我们先选出一个子集的刷子右移一步,超集和容易高维前缀和处理。你发现所有集合的转移总量是足够少的,故可以先不考虑限制把所有转移找出来,同时记录其颜色段,然后每次直接枚举所有转移判定即可。注意处理对第一列的限制。
P10683 [COTS 2024] 划分 Particija
先考虑原问题。
你考虑对每个点,两个划分中都有唯一一个包含它的,那么必须从二者中选出一个。可以建出二分图,对每个连通块取左右部点较小值即可。
考虑最小化答案。
我们发现我们需要分裂原连通块,而只要改的那一条边不是连接的两个孤点,存在方案将之连向一侧的连通块内部消除其影响,否则存在方案将其中一点加入某连通块较大一侧亦无影响,除非 \(n=1\) 特判即可。故只需找出所有割边,取其中对答案变化最大值即可。
考虑最大化答案。
我们发现我们需要合并原连通块,考虑如何选定最优连边对象,对一个左部点更少的块,我们会选定一个左部点更多的块与其相连,直接用左减右最大的块与其进行判定即可,反之同理。倘若选定的边是割边,先求出断边影响然后分别尝试为分出的两个块连边即可。
P10656 [ROI 2017] 学习轨迹 (Day 2)
倘若 \(a\) 序列选段一定,那么相当于给 \(b\) 序列划分出了若干子段,求其中最大价值的连续段。
倘若固定 \(a\) 选段左端点,动态右移右端点,那么相当于每次给 \(b\) 中一个段拆成两个,可以直接拿 set 维护。如果倒着做可以直接拿链表做到 \(O(n^2)\)。
硬做没有前途了,考虑发掘性质。你发现,若最终方案中两个序列都有选,则至少其一满足其元素和超过所在序列的一半,否则全选更大的序列不劣。
不妨钦定 \(b\) 序列选段超过一半,另一种可能本质相同,则首个前缀和超过一半的位置 \(p\) 在所有可能方案中必选,则只需维护在 \(p\) 左右最远能选到哪里即可。
在 \(a\) 序列上对选段右端点扫描线,维护每个左端点的答案,修改只需维护一个后缀 \(\min\) 和一个后缀 \(\max\),修改线段树二分覆盖即可,就做完了。
07.25
P17140 [NOI 2026] 线段
形成一棵树实际上就是要求没有点被覆盖至少三次并且选出的线段是连续一段。
将线段按左端点排序,然后维护 \(f(i,j)\) 表示选的右端点最长的是线段 \(i\),另一组右端点为 \(j\) 方案数,前缀和优化一下可以做到 \(O(n(n+m)K)\)。你发现,只要保证之前的选法合法,你不可能自己转移到自己算重,故而可以直接 \(f(i,j)\) 表示两组选段右端点分别为 \(i,j\) 即可,初始时枚举两条线段进行初始化,复杂度 \(O(Tn^2+nmK)\)。
P17141 [NOI 2026] 传送
对于任意局面,无论从任何节点使用传送门,其后的期望步数是一定的。因此局面固定时,一个点的答案就是直接走到 \(y\),或者走到最近的传送位置传送,二者较小值。那你发现,钦定完要走到 \(y\) 的点后,把剩下的点全都设作传送点是不劣的。
钦定走到 \(y\) 的点必然是一个连续段,我们记段内点数为 \(c\)、到 \(y\) 距离和为 \(s\),则走随机的期望步数 \(E\) 满足:
你注意到任意调整单点使其到根期望步数减小,\(E\) 不增,故而调整完的局面必然形如,与 \(y\) 距离不超过 \(lim=\lfloor E\rfloor\) 的直接走 \(y\),剩下的走随机。我们发现 \(E\) 关于 \(lim\) 是单谷,故而可以对每个 \(y\) 二分找到最终的 \(lim\),复杂度 \(O(n^2+m)\)。
瓶颈在于对每个 \(y\) 找 \(c,s\) 序列,树上邻域问题考虑点分树,复杂度 \(O(n\log^2n+m)\)。大常数选手原地爆炸。
你发现不用对每个 \(y\) 都二分,当 \(y\) 从一个点 \(a\) 移动到其相邻点 \(b\) 时,\(E\) 变化不超过 \(1\),从而 \(lim\) 变化也不超过 \(1\),故而我们对根节点二分之后对其余点只需进行 \(O(n)\) 次查询,复杂度 \(O(n\log n+m)\)。
P9329 [JOIST 2023] 两种货币 / Two Currencies
考虑找出路径上的所有站,那么必然贪心从小到大买。有一个简单的树上莫队套线段树。事实上可以在树上跑主席树,将两个端头的版本和 LCA 的版本合并起来即可得到路径信息,做到一个 \(\log\)。
07.27
[NOIP2026 模拟 R5] 图论之王 / #4225. Contact Tracing
注意到每个点得到信息的时间,要么是最后一次沟通前一天,要么是最后一次沟通,要么得不到。直接做即可。
[NOIP2026 模拟 R5] 王的盘缠 / #103. Money
每一段必须满足,内部元素不降,同时值域上不跨越之前已有的元素。任意前缀值域集合一定,同时跨不过去的间隙对于任意段来说都是跨不过去的,所以可以直接贪心,每次找到最远的位置开一段即可。
[NOIP2026 模拟 R5] 王的试炼 / P15721 [JAG 2023 Summer Camp #3] Many-hued Tree
考虑判定,你发现操作形态必然形如值域上从两边到中间逐步操作直到相遇。但你发现一个局面的可行操作方案不是唯一的,直接做可能会算重。
你考虑钦定从 \(1\) 一头能拓展就拓展,直到拓展不了然后再从右侧拓展过来。充分性显然,考虑必要性,若此时不合法,要么右侧拓展不过来,否则左右两段没有连边,右侧也无法再往左侧拓展,故而必然不合法。
考虑枚举最后一步合并时的那一条边,分别做其分出的两个连通块。考虑一个连通块,假如起点一定令作根,就是要求从根到叶子的所有路径不降,可以直接树形 DP 每次合并子树序列做。结果与合并顺序无关,故而是可撤销的,于是可以换根 DP 得到所有点为根的答案。
考虑如何不算重,不符合钦定条件仅当钦定的断边连接的两个端点都是各自序列上的最后一个,你发现可以直接在 DP 上开一维 \(0/1\) 表示钦定点是否在最后,转移是容易的。
[NOIP2026 模拟 R5] 王的加冕 / P16702 [MCO 2026] 雨水收集
和 R4 的墙是一个东西,不用神秘东西维护前缀后缀 \(\max\) 之和了,直接上一个单侧递归线段树就做完了。
P9331 [JOIST 2023] 护照 / Passport
任意时刻可达的都是一个连续区间,你发现路程必然形如一起走一段后分开各自走向 \(1\) 和 \(n\),线段树优化建图然后对每个点分别求出其到 \(1\) 和 \(n\) 的贡献和,最后跑一遍多源最短路即可。
07.28
ARC106E Medals
最优化并不好做。尝试二分答案后判定。首先答案上界是 \(2nk\),因为一个人的耗时不超过 \(2k\)。
可以建立二分图模型,每个人拆出 \(k\) 个左部点,右部点即各天数,要求存在关于左部点的完美匹配。
考虑霍尔定理。你发现一个人的 \(k\) 个点必然放在一起考虑不劣,那么就可以直接枚举左部点集。考虑求 \(|N(S)|\),你大可对每个天数预处理出其对哪些点连边,然后跑一遍高维前缀和,有交容斥成全集减无交即可。
复杂度 \(O((2^nn+n^2k)\log nk)\)。
#5312. Levenshtein Distance
先考虑怎么求编辑距离。经典地 \(f(i,j)\) 表示两个串匹配到 \(i,j\) 的距离。考虑到所求编辑距离很小,尝试换维。
你发现,当两串匹配部分长度差一定时,编辑距离关于串长单增。故考虑设计 \(f(i,j)\) 表示最大 \(x\) 满足 \(s[:x]\) 与 \(t[:x+j]\) 的编辑距离不超过 \(i\)。
考虑如何求 \(f(i,j)\)。首先你可以贪心地 \(f(i,j)\gets f(i,j)+\operatorname{LCP}(s[f(i,j)+1:],t[f(i,j)+j+1:])\),之后考虑编辑一个字符,用 \(f(i,j)\) 更新 \(f(i+1,j+1),f(i+1,j),f(i+1,j-1)\)。LCP 要用 SA 单次 \(O(1)\) 求。
注意到编辑距离不小于长度差,故而 \(j\in[-k,k]\),做一次是 \(O(k^2)\) 的。
考虑对 \(t\) 的每个后缀 \(t'\) 跑上述过程,那么对于 \(f(i,j)=|s|\) 的 \(j\),\(t'[:|s|+j]\) 与 \(s\) 的编辑距离不超过 \(i\)。统计答案最后做一个差分即可。
ARC125F Tree Degree Subset Sum
所有点度数之和为 \(2n-2\),不妨令所有点度数减一,\((x',y')\) 等价于 \((x,y+x)\) 唯一对应不影响答案,那么度数之和为 \(n-2\),也就是只有 \(n-2\) 个有效的 \(y\)。
那么现在就存在一个很好的性质,对于一个 \(y\),记其能取到的最小和最大 \(x\) 分别为 \(lb_y,rb_y\),那么 \([lb_y,rb_y]\) 中的每个数都能取到。
考虑证明这一性质,你记度数为 \(0\) 的点个数为 \(cnt\),则只需证 \([lb_y,lb_y+cnt]\cup [rb_y-cnt,rb_y]=[lb_y,rb_y]\),即证 \(rb_y-lb_y\le 2cnt+1\)。注意到,有:
故而 \(rb_y-lb_y\le 2cnt-2\),得证。所以你只需要对每个 \(y\) 求出最小和最大的 \(x\) 即可,你发现不同的度数只有 \(O(\sqrt n)\) 个,直接跑多重背包即可。
CF1342F Make It Ascending
你感觉到并不具有简单策略,顺次构造也需要得知上一位的值以及剩余元素。注意到 \(n\) 足够小。存在一个暴力是 \(f(i,S,v)\) 表示当前已经用了 \(S\) 中的元素,已经确定的最后一位值为 \(v\) 位于 \(i\) 的最少操作次数。
不太好做,但你发现操作次数不超过 \(n\) 次,考虑换维,\(f(v,S,i)\) 表示当前已经用了 \(S\) 中的元素,已确定 \(v\) 个数且最右边的数位于 \(i\) 时最右边元素的最小值。
每次直接枚举下一个确定数用了哪些数,然后再去枚举放置位置的话是 \(O(3^nn^3)\) 的,过不了。但你发现放置位置考前是不劣的,你只需要放到新选的数中最靠前的在 \(i\) 之后的数即可,故做到 \(O(3^nn^2)\),可以通过。
P6377 [PA 2010] Termites
类零和博弈,后手的策略等价于最小化先手的得分。各个 \(0\) 分出的若干连续段是独立的,每段都形如从两端向中间延伸,除两端的两个区间。
你先考虑只有一个段怎么做。
一个很 naive 的想法是每次取最大的一端,显然可能会露出一个更大值留给对手。注意该策略正确当且仅当原段为单谷。
然后很神秘的是,你注意到可以把原序列化成单谷。关键观察是,对于 \(a_{i-1}<a_i>a_{i+1}\) 的点,若你取了 \(a_{i-1}\),对手显然会取 \(a_{i}\),你下一步必然取 \(a_{i+1}\)。如果你下一步取了另一个端点,那第一步直接取过去而不是取 \(a_{i-1}\) 是不劣的。
也就是说,你每次可以直接把这样的峰合并,最后留下的就是单谷,直接执行上述 naive 策略即可。
现在考虑多个段的情况,在将所有段都变为单谷过后,同样直接跑上述 naive 策略即可。对于序列两端的两个段,考虑中间放一个极小值后拼在一起规约到一般段做。
CF717F Heroes of Making Magic III
你手摸一会发现相邻两个来回走可以替代所有走步方案,故而只需考虑相邻两个来回走的情况,相当于是从前到后相邻两两抵消。要求奇数位抵消到本位为正,偶数位抵消到本位非负。
抵消到每一位后的值可以表示为,从当前位到区间开头,加减交替运算上各位的值,查询只需查区间内奇数偶数位各自最小值即可,可以直接线段树维护。
#9934. Haitang and Rock Paper Scissors
你先考虑对于一个一定的序列 \(b\) 如何最大化得分。存在一个暴力是 \(f(i,j)\) 表示考虑到 \(i\) 做了 \(j\) 的最大得分,答案为 \(\max\{f(n,0),f(n,1),f(n,2)\}\)。
三个元素的 \(\max\) 很不好处理,但其中必然有一个值为 \(-\infty\),故而实际上只有两个元素在取 \(\max\)。
你注意到 \(n\) 足够小,不妨暴力维护两个值。直接把两个值放在下标里肯定炸了,但可以换维,定义 \(f(i,0/1/2,0/1/2,\delta)\) 表示考虑到 \(i\),有值的两种情况分别为何,情况一与情况二的价值差为 \(\delta\ge 0\) 时,情况一的价值和,再开一个 \(g\) 存方案数辅助转移就做完了。
#16331. Strategic Stones
最优化有点不好做。你考虑二分答案转判定问题。
初始给定的黑点将原序列划分成了独立的各段,对每段单独考虑,形如 0? 组成的序列,在已知答案之后你考虑双指针得到所有极短问号区间,满足将他们填上之后就可以得到符合条件的连续段。
若一个区间长度不超过 \(1\),那么显然可以满足。若所有区间长度均比 \(2\) 大,则必然满足不了。
考虑长度为 \(2\) 的区间。若其与另一个长为 \(2\) 的区间有交,则必然合法。否则,若其与一个长为 \(3\) 的区间有交,在交点放置后后手必然填当前区间,另一个区间长度变为 \(2\),对它继续做下去即可,每次二分判定这部分的总枚举量都是 \(O(n)\) 的。
07.29
AT_wupc2019_j Color Ball
你把所有桶首尾相接可以唯一映射一个排列。考虑贡献延后,球可以往前放。前面的空位数量恰等于前面要往后放的球个数。
故而 \(f(i,j)\) 表示考虑到段 \(i\) 有 \(j\) 个球要往后放的方案数,转移枚举当前段几个球放在前面,再枚举之前几个球放在当前段。可以分析出复杂度 \(O(n^3)\)。
考虑优化,瓶颈在于为保证不放在原桶必须确定球的去向,考虑对其做容斥,钦定若干球放在自己桶内,最后统一填入未钦定的所有球,视同色球作不同使统一填入时无需考虑各种类个数,只需维护已钦定球的个数即可。可以分析出复杂度 \(O(n^2)\)。
P11480 [NordicOI 2017] Yule Lads
首先所有质数是必须来的。你考虑对于一个合数,将他抛掉一个质因数,剩下的数必然有偶数个因数来了,那么该数本身来不来只在于该质因数的次数是否为 \(1\)。
故而要来的数满足 \(\mu\ne 0\)。\(n\) 有点大。
考虑容斥。首先平方因子不超过 \(\sqrt n\),你考虑枚举所有可能质因子组合,若其大小为 \(k\) 且乘积为 \(p\),那么其容斥系数为 \((-1)^k\),包含其的数有 \(\lfloor\frac{n}{p^2}\rfloor\) 个,直接求和即可。该过程可以简化为:
#14414. Nice Subsequences
存在一个暴力是 \(f(i,j)\) 考虑到 \(i\) 最后一个元素是 \(j\) 的最大长度。或者 \(f(i)\) 表示钦定最后一个元素是 \(i\) 前面能选到的最大长度。复杂度均为 \(O(n^2)\)。
考虑处理不互质。枚举质数,你发现可以对每个点维护其关于各个质因数的前一个位置,总量是 \(O(n\log V)\) 的,只可能从这些位置转移,直接跑上述第二个 DP 即可,记得给转移位置去重。
#18107. Parentheses
考虑转为折线,左括号视作 \(1\),右括号视作 \(-1\),维护前缀和 \(s\)。
你发现给定的操作并没有很好的描述方法,尝试分讨局面,默认 \(n\) 为偶数:
- 若 \(s\ge 0\) 恒成立并 \(s_n=0\),操作次数为 \(0\)。
- 若 \(s\ge 0\) 恒成立并 \(s_n>0\),你发现 \(s_n\) 也必然为偶数,故而必然存在 \(i\) 满足 \(s_i=\frac{s_n}{2}\),你直接操作 \([i,n]\) 段即可,操作次数为 \(1\)。
- 若存在 \(s<0\),首先你找到最后一个全局最小值位置 \(i\),操作一次 \([1,i]\) 段即可规约回 \(s\ge 0\) 的问题,故而操作次数必然不超过 \(2\),我们考虑何时操作次数为 \(1\)。显然,操作次数为 \(1\) 当且仅当 \(s_n\) 即为全局最小值。
并且你注意到,操作次数为 \(1\) 的两种情况方案数相同,因为一者的方案等价于倒着走另一者的方案,形成双射。于是容易格路计数求各方案数。记 \(m=\frac{n}{2}\),你把题目所求化简一下得到:
直接暴力约质因数算即可。
#15975. 分解重构
你注意到 \(m\) 是不大的,其约数个数是足够小的。故而你可以预处理出所有约数后直接做 \(f(i,j,k)\) 表示前 \(i\) 个数有 \(j\) 个不同乘积为 \(k\) 的方案数,转移有一个狄利克雷前缀和,直接做即可。
#16339. Logical Resonance
首先对于 A 树,你从根开始每次优先走最大的儿子,得到的 dfs 序可以与树形成双射:考虑后一位,若比自己大就是儿子,比自己小,若比父亲大就是兄弟,否则递归到父亲处继续构造。
你考虑把 dfs 序循环移位使得 \(n\) 在开头,将上述规则大小互换后同样可以双射一棵树,你发现恰好符合条件,因为原来是叶子的后一个数必然比自己小,否则后一个数必然比自己大,就做完了。
#15421. GPA Optimization Plan
你发现直接做有点困难,因为分子分母分别累和的形式并不等价于最大化各分数值。
考虑二分答案,判定 \(\frac{a}{b}\ge x\iff a\ge bx\),那么每个学期选的课程必然是 \(a-bx\) 最小的那一门或者补不选,直接上李超即可。
#15428. Tetris
求合法分组方案,满足每组内的元素不重复。考虑对每个元素维护其前一个和后一个出现的位置,要求他们之间有一个分界。
你直接开一个线段树维护所有位置是否可能是首个分界,对每个值开一个 set 维护位置信息即可。
07.30
P9309 [EGOI 2021] Number of Zeros / 零的个数
找 \(2\) 和 \(5\) 的最大次数即可。枚举次数然后看区间内是否存在其倍数。
P9310 [EGOI 2021] Luna likes Love / 卢娜爱磕 cp
一对情侣相遇后就会删除,因此他们的终止位置并不重要。显然每次选定一对情侣一直操作他们直到相遇不劣,那么成包含关系的被包含对需要先操作,此外就是相交关系,顺序并不重要。所以排序一遍直接开一个 BIT 模拟即可。
P9315 [EGOI 2021] Angry Cows / 感染的奶牛
首先你可以跑一遍多源最短路得到每个点的代价,那么二分答案,问题变为能否从一个特定点集中选出一些点使得 A 类点全部连通且没有 B 类点与 A 类点连通。
直接选点看起来不好操作,你考虑把可以选的点先全部选上,然后把当前各连通块跑出来,如果存在连通块既有 A 类点又有 B 类点显然不合法。然后你考虑从中开放一些点,你发现与有 B 类点的连通块有连边的点开放了也不能与 A 类点连通,直接不开放即可,那么剩下的点就可以全部开放,你开放完之后再搜一遍看是否所有 A 类点均已连通即可。
P9312 [EGOI 2021] Lanterns / 灯笼
任意时刻能从 \(i\) 走到 \(j\),当且仅当 \([i,j]\) 的区间最大值和区间最小值在值域上位于已购买区间形成的同一连续段内。你注意到可以钦定任意时刻,已购买的区间形成一个连续段,其余区间等后面需要的时候再购买即可。
于是存在 DP \(f(i,j,k)\) 表示已购买的值域区间形成连续段 \([i,j]\) 且当前位于 \(k\) 的最小代价,但这么设计是不太优的,你注意到任意时刻 \(i,j\) 都是某个特定区间的端点,故而考虑设计 \(f(i,j)\) 表示连续段为 \([l_i,r_j]\) 的方案,那么 \(p_i,p_j\) 必然位于序列上可达区间部分,就压掉了第三维。
还有一个枚举起点的问题,你倒序 DP 即可。
那么转移就有三种,拓展右端点,拓展左端点,同时拓展左右两端点。直接做即可做到 \(O(n^3)\)。考虑优化。
你发现,对于固定的 \(i\),\(r_j\) 越小,可达区间必然越小,你向右拓展的下一个区间 \(j'\) 需要满足 \(p_{j'}\) 可达且 \(r_j\ge l_{j'}\),那么当 \(r_j\) 减小时,原先不满足的区间在之后也必然不会满足,故而可以开一个小根堆,不合法的转移直接 pop 掉即可。向左拓展同理。
考虑向左右同时拓展怎么处理,形似 \(f(i,j)\gets f(k,k)\),你考虑将之拆成 \(f(i,j)\gets f(i,k)\gets f(k,k)\),其中间状态 \(f(i,k)\) 是非法的,不妨钦定其贡献为 \(f(k,k)\),然后正常转移即可。
最终复杂度 \(O(n^2\log n)\)。
#18175. Restrooms
一个 naive 的想法是,你从左到右扫一遍,对两个区间维护当前最小的右端点,然后填入右端点更小的那个。是错的。
你注意到,当所有区间长度均不小于 \(2\) 时,必然有解。考虑证明,首先区间更长限制更宽松,因此不妨令所有区间长为 \(2\),其次区间挨得越紧约严格,那你考虑两边都是一直叠的情况,你发现存在状似零一交替填入的解法,故而得证。
那么区间长为 \(1\) 又是必填,所以我们只需先把所有长为 \(1\) 的区间都填掉,最后的局面你跑上述 naive 的贪心即可。注意新出现的长为 \(1\) 的区间也要全部填完。你发现包含了其他同色区间的区间没有用,所以端点单调,然后就可以直接大力数据结构维护了。
#18173. Long Nim
先考虑先手必败的情况如何最大化步数。后手不能动比先手变化的位更高的位,你考虑往 \(\operatorname{lowbit}\) 最小的点思考。你发现,如果你选一个这样的点拿走 \(1\) 个,那么后手也只能再找一个 \(\operatorname{lowbit}\) 相同的点再拿走 \(1\) 个,操作步数即为 \(\sum a\)。
再考虑先手必胜的情况,显然只需在所有可行的位置中选一个能拿走最多的个数的位置即可。
07.31
#14974. Shiroi Album II
一条路径是否合法只需关注最大值 \(a\)、最小值 \(b\)、次小值 \(c\),更具体地,合法当且仅当 \(a<b+c\)。
你枚举最大边,然后双指针最小值和次小值,将次小值和最大值之间的边全部加上,对每对最小边更新 \(O(1)\) 对连通块的答案。并查集维护连通块同时建出合并树,用 bitset 做一下即可。\(O(n^2\alpha(n)+\frac{n^3}{w})\)。
并查集可能需要撤销,但是最后处理合并树的时候应当回到最终状态,也就是撤销撤销操作。
#14979. Shiratama
先忽略步数限制,考虑判定非法。
你考虑将奇数偶数位置分别排成两行,那么操作一即为交换两行上的数,操作二即为选择一个对角线交换其上两个点的位置。将其黑白染色,当 \(n\) 为偶数时,注意到黑白点集元素恒定,\(n\) 为奇数时 \(1\) 和 \(2n\) 允许交换。
先不考虑步数限制,对 \(2\mid n\) 的情况,只要每个点初始位置与终止位置颜色相同,必然有解,否则必然无解;对 \(2\nmid n\) 的情况,可以通过 \(1\leftrightarrow 2n\) 交换两点集元素,必然有解。
考虑构造满足条件限制的方案。
先考虑 \(2\mid n\) 的情况。显然思路是每次把要换的对角线换了然后统一来一次操作一。只考虑一个颜色的点集。不妨忽略头尾互换操作,你考虑冒泡,每次把 \(p_i>p_{i+1}\) 的可操作对都操作掉,这样一个颜色的总操作二次数显然不超过 \(\frac{n^2}{2}\),同时可以证明操作一次数是不超过 \(n\) 的。这样两个颜色一起考虑,操作次数符合条件。
考虑 \(2\not\mid n\) 的情况。你发现可以把白点黑点分别拉成一个序列,再将黑色序列拼在白色序列后面,重新标号一下就等价于一个序列的问题,操作二不超过 \(\frac{(2n)^2}{2}=2n^2\) 次,操作一不超过 \(2n\) 次,均符合条件。
#14975. Judgment of Mahou Shoujo
你考虑任意时刻死掉的点都是若干连续段,同时关键点只会是已死点或与已死点相邻的点,考虑设计 \(f(i,0/1,0/1)\) 表示从 \(i\) 到下一个活着的点 \(j\) 这一段,\(i,j\) 是否为关键点,区间最小关键点数。一个点死去后更新其左侧点的 DP 值即可。
注意到计算答案需要统一端点值,挂线段树上合并信息即可。
08.01
P17202 DKM OI Round 1 - 小猫的考试
手摸一下,你可以得到“稳定”的结构,也就是整棵树一直不变的结构。记 \(T_k\) 表示根值为 \(k\) 的稳定结构,\(T_0\) 只需要一个单点为 \(0\),\(T_k\) 构造方案为令根节点值为 \(k\) 然后其 \(k\) 个子节点对应子树分别为 \(T_0\sim T_k\)。显然 \(T_k\) 的点数是 \(2^k\)。
那么尝试让我们构造的结构形如,一直变化直到稳定下来,从而满足题意。但你发现很难设计一个不稳定结构使其逐步变化为上述稳定结构。
不妨尝试让一个稳定结构逐步变得不稳定。你发现这很简单,在一个 \(T_k\) 的最长链叶子后面再接一个 \(0\) 节点即可。手摸一下就会发现,值变化的只会是这条链,值为 \(0\) 的点会在 \(0,1\) 间反复变动,值为 \(v>0\) 的点开始变化后会在 \(v,v-1\) 间反复变动,只有值为 \(v\) 的点首次变为 \(v-1\) 后值为 \(v+1\) 的点才会开始变化。
直到值为 \(k\) 的点发生变化,下一刻时刻就会与上一个时刻的树完全相同。取 \(k=17\) 即可,有 \(2^{17}+1<200000\),你注意到在链底接几个零都无所谓,把空闲的点全都接在链尾即可。
08.02
#15315. Hamu
你考虑搜出一个 DFS 树,然后从根开始搜索一遍,回溯时如果子节点不满足条件就下去上来一次。这样除了根节点均可满足,总步数不超过 \(4n\)。
你注意到由于树是二分图,因此走出来的必然是偶环,存在这种情况当且仅当点权异或和为 \(1\),那么只要走一个奇环即可。确定异或和后在搜的过程中枚举非树边尝试额外走一圈回来即可,总步数不超过 \(5n\)。
注意题中图不一定连通且存在自环,容易处理。
08.10
AT_dp_w Intervals
考虑对填 \(0\) 的连续区间 DP。用总贡献减去完全被覆盖的部分贡献,后者容易离线扫描线得到。那你顺便把 DP 也挂到线段树上就做完了。
P6845 [CEOI 2019] Dynamic Diameter
直接上动态 DP 就做完了,但是码量略大。
树上直径是可合并的,一个点集的直径的两个端点必然在两个子集的四个端点中选出,你额外一个树剖维护深度然后直接把点挂线段树上即可。
P10833 [COTS 2023] 下 Niz
首先段中每个元素只能出现一次。不妨枚举段右端点,只需要关心最近的重复位置,故而只需关注每个元素最后一次出现的位置。
考虑判定一个区间是否符合条件,只需满足最小值为 \(1\),没有重复元素,且最大值恰为区间长度。前两个可以通过限定查询区间实现,考虑第三个限制。
在满足无重复元素的情况下最大值 \(\max\) 不小于区间长度 \(len\),故而考虑维护 \(\max-len\) 的最小值,每次找到最远的 \(\max-len=0\) 的区间。考虑把 \(len\) 拆了,转写作 \(\max+l-1=r\)。扫描线区间覆盖维护 \(\max\),线段树存一下最小值个数就做完了。
BZOJ3100 排列
和上一个题本质同构,但是空间格外小。
考虑抛弃数据结构。因为元素不重,所以考虑枚举区间内 \(1\) 所在位置,再枚举最大值所在一侧端点,这样复杂度为 \(O(n)\)。那么只需找到最远的另一侧合法端点即可,注意到可以直接双指针,复杂度仍为 \(O(n)\)。
P8860 动态图连通性
注意到多次出现的边,如果第一次没被删,后面一定删不了。所以只需保留每条边首次出现的操作。
考虑找出最后留下的一条路径。记各边被尝试删除时刻为 \(t\),保留下来的路径必然满足将路径上 \(t\) 升序排序后字典序最大。
考虑暴力去做这个东西,跑一遍 dijkstra 维护从 \(1\) 出发到每个点的最优路径,考虑主席树,字典序判定容易二分哈希实现。
但没有必要。你跑 dijkstra 的时候每次把相应边 \(t\) 最大的转移做掉即可,可以证明正确性。
#15318. Flower's land 3
神秘 ad-hoc。你考虑对每个 \(i\) 选出一个可能的 \(p_i\) 作为父亲,每次更新就从 \(1\) 开始 dfs,因为每条边异或位不超过 \(k\),故而搜一次即可 \(O(m+nk)\) 得到所有与 \(i\) 异或位不超过 \(k\) 的点。最终复杂度 \(O(nm+n^2k)\)。
#15326. Yet another 01 problem
考虑描述一棵合法的树。首先对于任意子树,其中所有叶子到子树根的异或和需求必须相同。对于一个点的两个子节点,其需求必须相反。
换句话说,你可以每次选两个值不同的相邻节点合并,新点权值可以任意钦定,要求最后得到一个 \(0\)。当两个子节点都不是叶子的时候,会有一个 \(2\) 的系数。求所有合法合并方案价值之和。
假如只求方案数的话,容斥钦定同色点配对即可。
考虑算上系数。两个儿子均非叶子不好算,但记两个儿子均为叶子的点数为 \(c\),那么容易证明两个儿子均非叶子的点数恰为 \(c-1\)。
考虑组合意义,\(2^c\) 可以视作任选 \(c\) 的一个子集,那么就可以将这部分和容斥一块处理,只需要对每个 \(i\) 求出钦定了 \(i\) 对的带系数方案数即可,剩余点任意合并是经典卡特兰数问题。
求每个 \(i\) 的带系数方案数直接分治大力卷积即可做到 \(O(n\log^2n)\)。
08.11
P10069 [CCO 2023] Flip it and Stick it
神金小分讨。
P8216 [THUPC 2022 初赛] 画图
神金小模拟。
P3541 [POI 2010] Monotonicity
存在一个 DP 是 \(f(i,j)\) 表示最后一位选了 \(i\) 匹配到 \(s\) 的第 \(j\) 位的最大长度。转移枚举 \(i,j\) 之后形如值域上区间求 \(\max\),直接给每个 \(j\) 开一个线段树就做完了。
#1443. Potato Shuffle
考虑按 \(\frac{k}{2}\) 将所有 \(a\) 划分成两部分,大数之间相对顺序一定,小数之间任意互换。考虑降序插入小数,那么大数将会升序解锁,用一个 set 维护一下尚不可跨越的大数位置,再开个 BIT 之类维护区间内已有点数即可,去重是容易的。
P5972 [PA 2019] Desant
尝试设计 \(f(S)\) 表示选了 \(S\) 中元素的逆序对数,非常平凡。可是不存下已有元素就很难顺次 DP。
然而,你存下已有元素的目的是方面后续查询比其小的数个数,那么实际上只需要记录后续元素将值域分段后每段的元素个数。由于一段的元素个数不超过段长,故状态数最大值即为“求和为 \(n\) 的数乘积最大值”状物,在 \(O(3^{\frac{n}{3}})\)。
故而直接做即可,复杂度 \(O(n^23^{\frac{n}{3}})\),远跑不满。
#891. Minimum Spanning Tree
考虑 Kruskal,对于任一条非树边,其权值必须比树上两端点路径边权最大值大,这是充要条件。
尝试先确定树边边权相对关系,然后将非树边插入其中。每条非树边的可插入位置形如一个后缀。考虑降序确定树边边权,那么每次会影响到“包含了这条边并且没有包含之前已经确定的边”的非树边,这样非树边插入的后缀长度单增,可插入位置个数一定。
容易 \(O(2^nn)\) 高维后缀和处理出每个边集覆盖的非树边集合大小,转移直接做差即可得到新增非树边数量,故而 DP 部分也是 \(O(2^nn)\) 的。
08.12
[NOIP2026 模拟 R7] 黑割点
\(n<k\) 和 \(\deg_t\le k\) 的情况是平凡的。考虑其余情况,A 的策略显然是尽量保证在 B 走到 \(\deg<k\) 的点时剩余白点数量 \(\ge k\),考虑在第一步尽量封锁子树大小较大的点,若下一步走到的点度数仍不小于 \(k\),那么已封锁的子树中白点数量必然不小于 \(k-1\),A 必胜,故 A 失败仅当 \(n< 2k\)。
[NOIP2026 模拟 R7] 甜筒的染色树
可行染色方案显然形如每次选一个完整子树染成黄色或蓝色,剩下的全是绿色。考虑求一棵树的方案数,有:
对此计数,设计 \(f(i,j)\) 表示大小为 \(i\) 方案数为 \(j\) 的无标号树个数,最后乘一个 \(n!\) 即可,转移枚举最后一个子结点子树大小 \(k\),有转移:
考虑优化。\(n\) 个点的树的方案不小于 \(2n-1\),将 \(v\) 提到外层,那么 \(i'\) 的枚举上界为 \(\frac{v}{2}\) 而 \(i-i'\) 的枚举上界为 \(\frac{j}{2v}\),拼起来复杂度是 \(O(V)\) 的,外层容易调和级数分析出 \(O(V\ln V)\) 的复杂度,故最终复杂度 \(O(V^2\ln V)\)。
[NOIP2026 模拟 R7] Cone Collection Foundation
无交的显然互不影响。考虑两个人有交,那么如果先把他们不交的部分走完最后再走他们有交的部分就非法,尝试再加一个人使得他们在同时走完之前必然使此人提前走掉,经过尝试,合法仅当 \(C=A\oplus B\),相当于分成三个长为 \(6\) 的段,每个人各占了两段。
尝试往该结构内加入更多的人,你发现可以加入更多的 \(6\) 段,只要任意两段都有一个人占即可。
拓展地,可以选取 \(k\) 个长为 \(d\mid 12\) 的段,占用 \(kd\) 的长度,需要 \(k\choose 12/d\) 个人。容易把所有可行的方法放出来,可以简单 DP 获取每个人数的最优放置方案或者向我一样手动为五十个数设计方案。
[NOIP2026 模拟 R7] 异或消除 / P12559 [UOI 2024] Zeroing the segment
记 \(h=\max_{i=l}^r\operatorname{highbit}(a_i)\),那么最终的 \(x\) 需满足 \(x\ge 2^h\),\(a\le x\) 的均只需一次即可消除,\(a>x\) 的均只需两次。故而一个区间的代价为 \(\min_{x\ge2^h}x+len+\sum[a_i>x]\),容易注意到 \(x<2^h+len\) 否则不优于 \(x=2^h\)。
将 \(\sum[a_i>x]\) 容斥为 \(len-\sum[a_i\le x]\),则只需求 \(\min_{x\ge 2^h}x-\sum[a_i\le x]=\max_{x\ge 2^h}\sum[a_i\le x]-x\),考虑霍尔定理的形式 \(\max |S|-|N(S)|\),尝试构造二分图转最大匹配,但是不好处理 \(x\ge 2^h\) 的限制。
记 \(f(x)=\sum[a_i\le x]-x\),注意到 \(f(2^h)\) 是容易得到的,而 \(f(x>2^h)=f(2^h)+\sum[2^h<a_i\le x]-(x-2^h)\),你对 \(\sum[2^h<a_i\le x]-x\) 构建二分图,那么左部点为 \(a_i\in(2^h,2^h+len)\) 的 \(a_i\),右部点为 \(2^h+1\sim 2^h+len-1\),同样地每个 \(a_i\) 向所有满足 \(x\le a_i\) 的 \(x\) 连边,此时只需求该图的最大匹配即可。
经典地,可以贪心处理此类二分图的最大匹配,允许按任意顺序处理左部点,每次找到最大的可匹配右部点进行匹配即可。
考虑处理区间查询。尝试倒着扫区间左端点,维护从左到右贪心匹配能匹配上的左部点集合,这样一个右端点的最大匹配只需查询该集合中下标不超过其的点数。
考虑插入一个新的左端点更新集合 \(S\),继续利用霍尔定理,对 \((2^h,2^h+n)\) 内的每个右部点 \(x\) 维护 \(\sum_{i\in S}[2^h<a_i\le x]-(x-2^h)\),找到最小的该值 \(>0\) 的 \(x_m\),删除下标最大且 \(a_j\le x_m\) 的 \(j\in S\) 即可。
对每个 \(h\) 跑一遍上述过程,用主席树维护一下集合 \(S\),每个 \(a_i\) 只需在处理到自己的 \(\mathrm{highbit}\) 的时候考虑,于是即可做到 \(O(n\log V)\)。
P17317 [KismetOI 2026 I] 作弊
先考虑求 \(n=k\) 时的 rating。一个很典的 trick 是对价值作差分,设计 \(f(i)\) 表示前缀尚未达到钦定值且当前距离钦定值为 \(i\) 的价值,初始有 \(f(i)=val_i-val_{i-1}\),特殊地 \(i=0\) 后维度不再变化表示已经到达,复杂度 \(O(k^2V^2)\)。
考虑对于一个一定序列,如何修改最优。容易设计 \(f(i)\) 表示考虑到 \(i\) 的最大价值,定义价值为新序列值较原序列产生的差值,有转移 \(f(i)=\max\{f(i-1),f(i-2)+D-p_i\}\)。考虑原情景,先忽略 \(n=k\) 的 rating 的系数,暴力做法是把最大价值放进状态维护方案数,\(O(nkV^2)\) 很不好过。
注意到 \(\delta(i)=f(i)-f(i-1)\) 是 \(O(V)\) 的,不妨转而将 \(\delta\) 放入状态,有 \(\delta(i)=\max\{0,D-p_i-\delta(i-1)\}\),那么有 \(f(n)=\sum \delta(i)\),在转移过程中贡献给答案即可,容易做到 \(O(nV^2)\)。
考虑处理 \(\le k\) 的部分的贡献与系数,考虑继承上文求 \(n=k\) 时 rating 的做法,额外开一维存储当前 \(\delta\) 值即可得到 \(n>k\) 部分各 \(\delta\) 的系数,同时新开一个状态相同的 DP 维护 \(\sum\Delta(val)\cdot \sum \delta\) 用以求这一部分对答案的贡献,复杂度 \(O(k^2V^3)\)。
注意到上文对一个序列的价值减去了 \(\sum p_i\),考虑恢复这个,仍需关心 \(n=k\) 时的 rating,你用一样的方法去维护 \(\le k\) 的部分的 \(\sum\Delta(val)\cdot\sum p\) 即可。
最终复杂度 \(O(nV^2+k^2V^3)\)。
08.13
#2533. Two Buildings
如果 \(i\) 更小且 \(h_i\) 更大显然是不劣的,如果 \(j\) 更大且 \(h_j\) 更大显然也是不劣的,因此必然满足 \(i\) 是前缀 \(\max\),\(j\) 是后缀 \(\max\)。容易推式子证明此情境下,\(j\) 单增最优决策点单调不降。故而分治即可。
#846. 传送门
如果你也思维僵化那么直接线段树优化建图即可。但是 \(n\le 10^3\),所以可以直接给每个区间开一个出点和一个入点,\([l,r]\) 与 \([l+1,r],[l,r-1]\) 连边即可。
#9698 Twenty-two
考虑一个操作一 \(c_1\) 和一个操作二 \(c_2\),若 \(c_1\ge c_2\) 那二者互不影响,若 \(c_1<c_2\),若先操作 \(c_1\) 则区间全都会变成 \(c_2\),若先操作 \(c_2\) 则区间全都会变成 \(c_1\)。
那么首先给所有操作一按 \(c\) 升序排序,那么你每个操作二 \(c_2\) 可以任意选一个 \(c_1\le c_2\) 将这个操作描述为区间取 \(\max\) 为 \(c_1\),然后操作一就没用了,直接忽略不大于 \(c_{1\min}\) 的 \(c_2\),\(a\) 序列也没有用,只需关心各修改后的操作二的影响。
考虑设计 \(f(l,r,v)\) 表示区间 \([l,r]\) 操作后最小值 \(\ge v\) 的方案数,强制按值域降序考虑,考虑转移,维护一个辅助数组 \(g_i\) 表示用区间 \([l,r]\) 内的线段操作使得 \([l,i]\) 中所有数 \(\ge v\) 的方案,转移去枚举一个 \(=v\) 的位置与其后 \(>v\) 的连续段,复杂度 \(O(n^5)\),卡卡能过。
#12109. Nasty Donchik
考虑一个颜色 \(c\),显然只需关心相邻两个 \(a=c\) 的位置的限制,限制总个数在 \(O(n)\)。
考虑对 \(k\) 扫描线,维护各 \(j\) 的 \(i_\max,i_\min\),显然 \(k\) 增加二者均单减,在扫到 \(k\) 的时候将 \(j<k\) 的 \(i_{\max}\) 对 \(lst_{a_k}\) 取 \(\min\) 保证右块有的元素左块均有。
考虑保证左块有的元素右块均有,当 \(j< lst_{a_k}\) 的时候 \(k\) 没有影响,故只需维护 \(lst_{a_k}\) 左侧首个没有在 \((lst_{a_k},k]\) 出现过的元素 \(x\),此时合法仅当 \(i>x\),故将 \(i_\min\) 对 \(x\) 取 \(\min\) 即可,但关心 \(lst_{a_k}\) 右侧首个最后一次出现的元素 \(y\),则上述修改只对 \(j<y\) 的 \(j\) 生效,否则其限制应由 \(y\) 制得。
直接这样做要求 \(\sum\max\{0,i_{\max}-i_{\min}\}\),略微繁琐,你在对 \(i_\max\) 取 \(\min\) 的时候顺手也给 \(i_\min\) 取一下即可只求差值了。注意到 \(k\) 一定 \(j\) 增加 \(i\) 单增,故而取 \(\min\) 操作可以直接做成区间覆盖。
08.14
[NOIP2026 模拟 R8] 最大数码 2 / #18310. 最大数码 2
大力数位 DP 即可,维护位数、\(x\) 前缀最大值、\(x\) 是否得到最大值、\(a\) 前面是否抵着上下界、\(b\) 前面是否抵着上下界、凑出 \(x\) 上一位是否需要进位。
[NOIP2026 模拟 R8] 饺子 / #12561. 饺子
显然每个元素的贡献随次数单降,容易得到一个 \(O(m)\) 的贪心做法。
考虑优化,显然地考虑快速维护前 \(m\) 大的元素与各前缀和,你发现很难实现。假如我们有了这个,只需要考虑在 \(m\) 个以内把所有非负数取完、尝试取到 \(l\) 和尝试取到 \(r\) 三种情况。
你考虑在一次查询尝试取到 \(x\) 时二分第 \(x\) 大的元素 \(v\) 是多少,每次枚举 \(n\) 个点将其 \(>v\) 的元素全部取上,然后统计 \(=v\) 的元素个数,即可得到所求。
[NOIP2026 模拟 R8] 逐层评审 / #15496. Varză Murată
考虑二分答案转化为 \(01\) 串问题,修改类型只影响 \(01\) 块交界部分保留的值。
对于 \(\max\) 操作,他会将每个 \(0\) 连续段长度减一、每个非边界的 \(1\) 连续段长度加一,\(\min\) 操作同理。你维护一下连续段,再维护偏移量 \(\delta\),不妨钦定 \(1\) 段段长加 \(\delta\) \(0\) 段段长减 \(\delta\) 得到各自真实值,对各段长开一个 vector 存段编号,相邻关系用链表维护。
考虑一次修改,首先更新偏移量,然后手动修改边界上的段的长度,再将长度为 \(0\) 的段删去。删除无需使用 set,只要段最新长度与该下标不符跳过即可,故单次可以做到 \(O(n)\),最终复杂度 \(O(n\log n)\)。
[NOIP2026 模拟 R8] 优子序列 / #17745. K-Good Subsequences
考虑求一个序列的 \(K\),没有模拟外的合适方法。
考虑求一个序列的最长 \(K\) 好子序列。容易有一个 DP \(f(i,j)\) 表示考虑到 \(i\) 最后一个值是 \(j\) 的最长 \(K\) 好子序列长度,转移是一次区间 \(\max\),容易线段树 \(O(n\log n)\) 实现。
考虑原问题,直接 DP 套 DP 很没有前途。
关心初始 \(n=0\) 的情况,设计横轴为值域纵轴为 \(f\),点 \((x,y)\) 若有元素表示存在一个 \(a_i=x\land f(i,x)=y\),容易发现可以在值域上每 \(k+1\) 个放一列 \(l\) 个元素,答案即元素个数 \(l\lceil\frac{m}{k+1}\rceil\),显然没有更优答案。
那么先 \(O(n\log n)\) 得到原序列的 \(f\),考虑在此基础上构造。不妨对纵轴从下到上考虑加点,若考虑到 \(v\),那么 \(f<v\) 的所有元素对他没有任何影响,只需保证其区间内没有 \(f\ge v\) 的元素就可以加入。那么所有 \(f\ge v\) 的元素将值域划分成了若干连续段,对每个连续段执行 \(n=0\) 的构造策略即可,容易做到 \(O(n\log n)\)。
P10685 [COTS 2024] 兔子 Zečevi
考虑二分答案判定,应保证任意非终止时刻任意兔子能量非零。
考虑形式化上述要求,不妨将各物品拆成多个价值为 \(1\) 的,那么一只兔子应当得到 \(\max\{len-p_i,0\}\) 个物品,其得到的第 \(j\) 个物品下标应当在 \([x_i,x_i+p_i+j-1]\) 内。
容易视作二分图匹配,此类问题显然可以贪心,每个物品与其右侧右端点最小的 \(t\) 个区间匹配即可,容易扫描线权值线段树维护。
P10055 [CCO 2022] Good Game
长度超过 \(2\) 的同色段均可被删完,考虑压缩同色连续段作一点,\(0\) 表示段长为 \(1\),\(1\) 表示段长大于 \(1\),则只需关心这一新序列 \(a[1:n]\)。
考虑删除一个 \(1\),若它在边界则不会有任何影响,否则他会将左右两侧的点合并,必然形成一个新的 \(1\),你发现可以视作同时删除了其左右两个点。
那么,若 \(2\not\mid n\land a_{\lceil\frac{n}{2}\rceil}=1\) 必然有解。考虑 \(2\not\mid n\land a_{\lceil\frac{n}{2}\rceil}=0\) 的情况,你注意到若存在长不小于 \(\lfloor\frac{n}{2}\rfloor\) 的 \(0\) 连续段,则此段必然无法被消完,无解。否则,你找到中点 \(m=\lceil\frac{n}{2}\rceil\) 左右首个 \(a_i=1\) 的位置 \(l,r\),若要使中点移动到 \(r\),只需操作 \(r-m\) 次 \(l\) 位置,而 \(r-l\le \lfloor\frac{n}{2}\rfloor<m\implies l>r-m\),故而必然可行。
考虑 \(2\mid n\) 的情况,注意到进行一次非边界的消除不影响段长奇偶性,故若合法最后必然留下两个 \(1\),枚举分界点划分成两个奇长序列分别判定即可。
08.15
前缀最大公约数
考虑邻项交换,你把与之前部分的 \(\gcd\) 更小的放到前面是不劣的。由此贪心,只需维护每个数与已选数的 \(\gcd\) 每次选最小值即可。注意到当所有数该值一定时后缀 \(\gcd\) 不再变化可以直接算答案,而 \(\gcd\) 最多变化 \(\log V\) 次,故而每次暴力做即可,复杂度 \(O(n\log V)\)。
平衡子序列
考虑左括号上升右括号下降画出折线图,注意到最低点 \(v\) 即为失配右括号数,即 \(v=m-k\)。判一下 \(k\ge \min(n,m)\) 然后直接跑反射容斥即可。
机器人手臂
容易考虑转切比雪夫坐标独立两维,那么若有两点坐标奇偶性不同必然无解,因为对一个值取正负产生的差值为偶数不影响奇偶性。
先考虑坐标为奇数的情况,容易构造 \(2^0\sim 2^{30}\) 共 \(31\) 个数,从大到小设计方向即可,期望坐标在当前坐标哪一侧就选哪一边,如果越过越界值必然可以由更小的数凑出来。再考虑坐标为奇数的情况,你给 \(x,y\) 同减一然后额外加一个操作距离 \(1\) 最后补回来即可。
08.17
AT_utpc2024_a Array Similarity
考虑倍增哈希。
P15149 [SWERC 2024] Phryctoria
考虑如何判定一个缩写合法。对两个串顺次贪心匹配判定,合法仅当 \(s\) 可行而 \(t\) 不可行。
设计 \(f(i,j)\) 表示 \(S\) 匹配到 \(i\)、\(T\) 匹配到 \(j\) 的最短缩写长度,考虑转移,枚举 \(S\) 的下一个匹配段 \(S[l:r]\),需要找到 \(j'\),则 \(j'\) 需满足 \(S[l:r]=T[j'-(r-l):j']\land j'>j+r-l\),容易预处理。对 \(i\) 作一个前缀 \(\min\) 就做完了。
注意如果开头或结尾不带 * 要特殊处理,两串此时必须同时从开头或结尾起配。
#8253. Very Important Edge
考虑 Kruskal,显然只有删掉树上边有用,新增的边必然是连接两个部分的边权最小的边,直接上树剖然后枚举删掉的边即可。
#9312. Random Dungeon
考虑任意时刻决策只与已选的点集有关,而与此前的决策无关。考虑倒序 DP,容易设计 \(f(S)\) 表示最后一段点集为 \(S\) 的最大期望,转移枚举第一个出现的数,对继续或不继续两种情况取 \(\max\) 即可。
容易注意到,一个集合第一个出现的数越大,越可能选择不继续,因此任意时刻必然存在一个分界 \(k\),若出现的数比 \(k\) 小必然不继续,否则必然继续。随着轮数增加 \(k\) 是不降的,因为一直在抽要继续的更小的数,本来要继续的此后仍然要继续。
回到倒序 DP,那么每次的局面均形如一个后缀带上前面一串散数,你注意到如果选到比 \(k\) 小的数必然继续,否则必然停止,那么比 \(k\) 小的数具体是哪些已经不重要了,大可直接钦定 \(|S|=i\) 的集合均为前 \(i\) 大的数,可枚举 \(k\) 转移:
显然 \(k\) 就是首个 \(a_k> f(i-1)\) 的位置,又已知单调性,故可以 \(O(n)\) 转移。
P10285 [USACO24OPEN] Activating Robots P
首先容易有一个 \(f(S,x)\) 表示填了 \(S\) 中的点最后在激活点 \(x\) 的最小时间,转移枚举去到的激活点和填的机器人,复杂度 \(O(2^Rn^2R)\)。
考虑优化,你考虑无需枚举填的机器人,走到一个点后你必然会填此后首个到达该点的机器人,直接二分即可,\(O(2^Rn^2\log R)\)。
考虑优化,你发现机器人和激活点没有本质区别,考虑视作走到某个机器人处然后等激活点过来,复杂度就变成了 \(O(2^RR^2\log n)\)。
考虑优化,瓶颈在于每次都要二分最近的激活点,然而你发现先不激活最小化到达时间是不劣的,故而可以先处理出这一值再二分,复杂度 \(O(2^RR(R+\log n))\)。
08.18
[NOIP2026 模拟 R9] DP
奇异搞笑诈骗。注意到拼尽全力无法模拟 \(x=5\),结论是 \(x\ge 5\) 全部无解,\(x\le 4\) 直接手模即可。
[NOIP2026 模拟 R9] 线段树
显然唯一难点在于维护 \((x,y]\) 段的最小值,一个思路是每次 \(x=y\) 的时候建一棵笛卡尔树,另一个思路是再开一个中间指针 \(z=\lceil\frac{x+y}{2}\rceil\),维护 \(z\) 到 \(x+1,y\) 的前后缀 \(\min\),然后每次碰到 \(z\) 都重构,复杂度显然都是 \(O(n)\) 的。
[NOIP2026 模拟 R9] 博弈论 / #10905. Kaiji!
理解题意后容易有一个二分答案的算法,设计 \(f(i)\) 表示考虑到 \(i\) 在保证前缀胜率不小于 \(w\) 的前提下最多能为 \((i,i+1)\) 留下多大的概率,转移 \(f(i+1)\gets1-\max\{0,2w-f(i)\}-w[cnt_{i+1}>1]\),当 \(f\) 为负就返回非法,否则合法。但是本题要求取模,不好二分。
尝试将 \(f(i)\) 写作关于 \(w\) 的一次函数形式 \(a-bw\),考虑处理 \(\max\{0,2w-f(i)\}\),\(2w-f(i)\) 是关于 \(w\) 单增的,相当于你会选一个前缀将其覆盖成 \(1-[cnt_{i+1}>1]w\),而对于剩下的部分则只需给 \(a,b\) 各加上 \(1,2+[cnt_{i+1}>1]\),直接视作分段函数维护每段的 \(a,b\),顺次枚举 \(i\),每次暴力从前往后推平,然后打一个全局加 \(tag\)。
去掉非法情况同理,对于每个 \(i\) \(f(i)<0\) 的必然是一段后缀,从后往前直接删掉即可,这样最后留下的最后一段右端点即为答案。
[NOIP2026 模拟 R9] 图论 / P7418 [USACO21FEB] Counting Graphs P
难点在于读懂题意,见微近做题记录。
#9220. Bus Analysis
你买票的时间必然是恰好停在某个站的时间,容易有一个 DP \(f(i,x)\) 表示考虑到第 \(i\) 个站,花费 \(x\) 元最远能到达的超过 \(a_i\) 的距离,注意到记 \(x_0\) 为首个 \(f(i,x)\ge a_i\) 的 \(x\),那么有效的 \(x\) 只有 \(x_0,x_0+1,x_0+2\),更大的 \(x\) 不优。
对此计数,容易有一个 \(F(i,x,f(i,x),f(i,x+1),f(i,x+2))\),转移就 \(F(i,x)\to F(i,x)\) 或者 \(F(i,x)\to F(i,x+1)\)。考虑优化,首先扔掉 \(x\) 维度,转移 \(F(i,x)\to F(i,x+1)\) 时给答案加上产生的 \(\delta=1\) 乘可能方案数即可。然后你后面三个维度转而维护 \(f(i,x)-a_i\) ,该值不超过 \(75\),就做完了。
AGC036F Square Constraints
形如要在一个扇形中间放点成排列。倘若只有上界限制 \(R\) 没有下界限制 \(L\) 是好做的,按 \(R\) 升序排序,则第 \(i\) 个点的放点方案数为 \(R_i-(i-1)\)。
那么考虑下界限制,存在两个性质:
- 上界关于下界不降。
- 有下界的点中最小上界大于最大下界。
考虑容斥,对每个 \(k\) 求出恰有 \(k\) 个点放到下界以下的方案数,容易设计 \(f(i,j)\) 表示前 \(i\) 个点钦定了 \(j\) 个非法点的方案数,我们希望的填数顺序是,先按各自上界顺序把 \([n,2n)\) 内的点和 \([0,n)\) 内要填到下界之下的点填了,最后去填 \([0,n)\) 中不钦定在下界之下的点。
由性质 \(2.\),所有钦定在下界之下的点和 \([n,2n)\) 中的点均会影响 \([0,n)\) 中不钦定的点,只须考虑 \(R\) 比他小的同类不钦定点数量 \(c\),其方案数为 \(R_i-n-k-c\)。由性质 \(1.\),对 \([n,2n)\) 中点以 \(R\) 为关键字、对 \([0,n)\) 中点以 \(L\) 为关键字排序即可,那么 \([0,n)\) 中点的 \(R\) 也是升序的,然后就可以直接做了。需要枚举 \(k\) 再去跑 DP,复杂度 \(O(n^3)\)。
08.19
#3823. Mountain hike
给定一个 DAG,给定两个起点和终点,找到相应的两条点互不相交路径,求出最小总长度或输出无解。
设计 $ f(x,y)$ 表示两条路径分别走到了 \(x,y\) 的最短长度和,若两点互不可达就同时转移或者只动一点,否则就只动拓扑序更小的那个点,复杂度是 \(O(n^2+nm+m^2)\) 的。
特殊地,当 \(t1,t2\) 相互可达需要特殊处理,若 \(t2\) 拓扑序更大,就枚举 DP 到了 \(t2\) 的哪个祖先然后更新答案,注意该祖先不能是 \(t1\) 的祖先。
#3083. Bit Operation
容易有一个区间 DP,\(f(l,r,0/1)\),转移枚举分界点与操作然后归并一下操作序列即可。
注意到若相邻两个数数值相同,操作结果与操作类型无关。考虑维护连续段,每次要么删除一个连续段内部点,要么操作边界,你发现操作边界结果也是删除二者之一的一个点。
你发现可以简化上述过程,数值相同大可直接钦定某一操作删除一侧点另一操作删除另一侧点,那么你操作只剩下删点,相当于不在边界上的点有两种删法、在边界上的点只有一种。
枚举最后保留下来的点 \(i\),只需关心其两侧删完的方案数然后把操作序列归并即可,考虑一侧 \(x\) 个点操作方案,初始一共有 \(2x-1\) 个删点方案,任意删一个点都会减少两种删点方案,故答案为 \((2x-1)!!\),直接做即可。
#10516. 最近公共祖先
枚举 \(z=\mathrm{lca}(x,y)\) 你先找出两棵树上同时以 \(z\) 为祖先的点,那么 \(x,y\) 只能在其中选。
考虑容斥,任意选点方案数减去在一棵树上在同一子树内的点对数加上在两棵树上均在同一子树内的点对数。你把一棵树摊平成 DFS 序,那么就是在另一棵树上二维数点,即可得到同时以 \(z\) 为祖先的点数,再分别枚举子树即可得到第二个值。但你发现第三个值很难求,没有前途。
考虑 dsu on tree,你对第一棵树每个点维护一个其子树内点在第二棵树上的位置,合并子树时搜一遍该子树内的点,那么原树内与其产生的合法点数两个区间查即可。
P9001 [CEOI 2022] Parking
忽略已经完成配对的车,考虑每个车位上面的车向下面的车连边,那么一个颜色可以完成配对当且仅当其入度为 \(0\) 且出度不超过 \(1\),配对之后就可以将其出边删除。一个空位相当于可以自由删一条边。
注意到每个点度数不超过 \(2\),所以生成图是由若干个环和 DAG 组成的。考虑按拓扑序处理 DAG。在所有入度为零的点中,出度为 \(0\) 的处理掉会送你一个空位,出度为 \(1\) 的直接删掉没有任何影响,出度为 \(2\) 的需要消耗一个空位。剩下的就是环和存在出度大于 \(2\) 的点的连通块。
你先考虑处理链状物连通块,只需要一个空位,顺序处理度数为 \(2\) 的点,处理一个就会返回至少一个空位。再考虑剩下的环状物连通块,关心其出度为 \(2\) 的点数 \(c\),那么 \(c\le 1\) 均只需一个空位,并且最终返回至少一个空位,\(c\ge 2\) 的均只需两个空位,且最终返回至少两个空位,优先处理前一种再处理后一种即可。
#5504. Flower Garden
考虑 2-sat,要求形如“若 \([a,b]\) 中有黑点则 \([c,d]\) 中全是黑点”,容易考虑一个线段树优化建图。
初始时令所有点为白点显然是合法的,考虑调整满足 \(2n\) 的限制。首先若存在元素个数 \(>2n\) 的 SCC 必然非法,否则至多只有两个 SCC 大小 \(>n\)。
如果不选大小 \(>n\) 的 SCC,只要能选的大小和不小于 \(n\) 就必然有解。否则你若选了一个大小 \(>n\) 的 SCC,只需最小化其余选的大小和,看只选他能到达的所有 SCC 大小和是否 \(\le 2n\) 即可。
#9540. Double 11
首先将 \(s\) 升序排序,显然每组都会是一个连续段。重定义 \(s_i\) 表示第 \(i\) 段的 \(s\) 和、\(l_i\) 表示第 \(i\) 段的长度,那么限定为 \(\sum k_is_i=1\) 取等不劣,要求最小化 \(\sum\frac{l_i}{k_i}\)。由柯基不等式:
取等当且仅当 \(\frac{l_i}{k_i^2s_i}\) 均相等,显然存在正实数 \(k_i\) 满足条件。
故现只需最小化 \(\sum\sqrt{l_is_i}\),打表发现满足四边形不等式可以二分栈做,然后 \(m\) 的限制 WQS 二分即可。
08.20
[NOIP2026 模拟 R10] 项目分配 / #1173. Knowledge Is...
我们只需要最大化配对数量即可。按 \(r\) 降序贪心,维护未匹配区间的堆,与已匹配区间左侧区间的堆。考虑加入一个区间,如果能与一个未匹配区间匹配就匹配,否则你尝试用他把已匹配区间中左端点更大的替换出来,因为当前区间右端点必然比已匹配区间右端点小所以必然可以替换,那么你换一个左端点更大的点用于后续匹配必然不劣。
[NOIP2026 模拟 R10] 四向联结 / #17855. Crosslink
显然可以视作,找出一条连接左右的链,然后找两个点走向上下边界,重合显然更劣,且必然可以由别的方案替代,直接跑最短路即可。注意到边权很小,有 \(dis\le Vn\),于是最短路可以不带 \(\log\)。
[NOIP2026 模拟 R10] 楼层任务 / #17634. Tasks from Sasha
容易考虑容斥处理 LCA,用子树内任意选点方案数减去只在一个儿子的子树内选点的方案数。那么容易有一个 DP \(f(i,j)\) 表示子树 \(i\) 内有 \(j\) 个空余点可供祖先选择的方案数。
第二维的状态设计很不优秀,考虑优化,你发现可以进行选择的祖先足够小而空余点很大,故而反向考虑,让每个点去选一个祖先,设计 \(f(i,j)\) 表示考虑到子树 \(i\) 有 \(j\) 个祖先可供选择的方案数。
继续优化,你发现关键点数很少,考虑建出虚树,这样第一维就也是 \(O(k)\) 的,转移枚举子树时,两个虚树上点之间的部分方案数是好求的,记有 \(x\) 个祖先可选且这一块点数为 \(sz\) 则其方案数为 \(x^{sz}\)。
但这样还有一个小问题,有的子树内部没有关键点不在虚树上,而关键点存在钦定只在其中选点的需要,你如果对关键点枚举这样的儿子的话复杂度是 \(O(nk)\) 的。注意到这样的子树内方案数只与可选祖先个数与子树大小有关,而子树大小和是 \(O(n)\) 的,对每个关键点枚举其本质不同 \(sz\),相同 \(sz\) 的多个子树一次计算,可以得到枚举量是 \(O(k\sqrt{nk})\) 的。
最终复杂度 \(O(n+(k^2+k\sqrt{nk})\log n)\),可过。
[NOIP2026 模拟 R10] 旋转齿轮 / #13154. Rotating Gears
显然考虑以深度最浅的点为一个连通块的特征。考虑描述 \(y\) 在 \(x\) 的连通块内,记 \(c(x)\) 表示 \(x\) 到根路径上被删除的点数,则二者联通当且仅当 \(y\in \mathrm{subtree}(x)\land c(x)=c(y)\)。
考虑一次操作,先找到操作点所在连通块,你树剖对每条重链用 set 维护被删点集,那么容易一个 \(\log\) 实现,只需关心集合最小值即可确定答案是否在这条链上,在再二分具体位置即可。
然后有一个巧妙的实现,你对线段树上每个区间维护区间 \(\mathrm{lca}\) 的 \(c\) 信息,对连通块 \(x\) 的操作,找出 \(x\) 子树的 \(\log\) 个 dfn 区间,一个区间有效仅当区间 \(\mathrm{lca}\) 的 \(c\) 与 \(c(x)\) 相等,那么对一个区间的标记下传或信息上传,当且仅当子区间 \(\mathrm{lca}\) 的 \(c\) 与父区间一致。
实现上,你并不关心区间 \(\mathrm{lca}\) 的具体数值,每次加点删点时找出相应点子树的 \(\log\) 个 dfn 区间直接对 \(c\) 区间加即可。
08.21
#17045. ZUMA
考虑 \(f(l,r,c)\) 表示消 \([l,r]\) 且 \(r\) 之后预留有 \(c\) 个与 \(r\) 同色的点的最小代价。注意到 \(c>5\) 没有意义。考虑转移,要么给 \(r\) 消掉,要么并给之前的某个同色点,故而可以做 \(O(n^3k)\)。
#7153. XOr
最终答案一位可以为零仅当所有组这一位均为 \(0\),也就是所有组这一位均有偶数个 \(1\)。那么如果某个位有奇数个 \(1\) 在最终答案中必然为 \(1\)。
从高到低处理,判定答案这一位可否为 \(0\),同时考虑更高位中钦定为 \(0\) 的位,注意到组数一定时,右端点更小必然不劣,因为剩余段各位信息奇偶性恒定。故而可以贪心判定,任意时刻能分就分,分出来有 \(m\) 组就合法。
#5059. Plants vs Zombies
模拟题。以时间为第一关键字、索引为第二关键字排序,那么豌豆显然是在顺序攻击。你关心前缀最晚死亡时间,在此前无需考虑豌豆影响,否则必然考虑豌豆影响,二分能走的时间即可。
#12121. Golf
若分母为二的幂次是好做的,构造一条链然后向两个终点连边即可。
你发现可以用环对分母二进制构造。对一个 \(k\) 个点的环,除了起始点和最后点,剩下的点的额外边要么连向环外点要么连向起始点,若连向起始点记其概率为 \(x\),最终对起始点可以得到 \(2^k-\sum x\) 的分母。
你发现你有三个需求:以 \(\frac{a}{2^k}\) 的概率走向 \(1\)、以 \(\frac{b}{2^k}\) 的概率走向 \(2\)、以 \(\frac{2^k-a-b}{2^k}\) 的概率走向起始点。
不妨将起始点也视作终点之一,倒着构造,任意时刻三个点 \(i,j,k\) 的三个需求 \(x,y,z\) 中必然没有或有两个是奇数,令其作 \(y\le z\)(全是偶数任选两个均可),新建一个点 \(t\) 连向 \(j,k\) 并令 \(j'\gets t\),则 \(x=x'\)、\(y=\frac{y'}{2}\)、\(z=\frac{y'}{2}+z'\),下一步分母减半故分子也减半,最终形式即 \(x'\gets \frac{x}{2}\)、\(y'\gets y\)、\(z'\gets \frac{z-y}{2}\),直到 \(x=0\land y=z=1\) 结束,构造次数即点数是 \(\log V\) 的。
P4689 [Ynoi Easy Round 2016] 这是我自己的发明
考虑莫队,倍长 dfn 序解决子树包含父亲的区间,考虑容斥,拆成四对前缀跑莫队即可。那么只需快速得到每次查询两个子树的区间即可,若根不在子树内则就是原子树,否则从根倍增跳一下即可。
P9247 [集训队互测 2018] 完美的队列
考虑对每次操作,维护它加入的节点最晚被删除时间,一个颜色的多次操作取并集即可。
考虑分块。考虑整块,双指针预处理出每个块每个时刻的答案,需要维护一个区间加整体查状物,分块直接做即可。考虑散块,把查询离线下来,然后跑一遍扫描线树状数组上二分即可,复杂度 \(O(m\sqrt{n\log n})\)。
但是可以 polylog。考虑线段树,对于每个区间,仍尝试双指针预处理,直接做显然很炸,你考虑与一个区间有交但不为包含关系的操作数量是 \(O(\log n)\) 的,关心完全包含的关系,按深搜顺序处理区间,搜索过程中动态维护一个树状数组存储完全包含的操作信息,其修改总量是 \(O(n\log n)\) 的,对一个区间双指针答案,只双指针非包含的有交区间,包含关系在树状数组上做一下即可,复杂度 \(O(n\log^2n)\)。
08.22
[NOIP2026 模拟 R11] 总评
余数为 \(1\) 显然最优,判一下 \(c=0\) 和 \(b=1\) 的剩下的方案数就是 \(\lceil\frac{c}{b}\rceil\)。
[NOIP2026 模拟 R11] 命运之树
树形 DP,对每个子树维护子树内统计奇数贡献 \(fo\) 和偶数 \(fe\) 贡献各自的最大值,转移仿佛和子树顺序有关,但你注意到只要有奇数大小子树,所有偶数大小子树能自由选择贡献 \(fo\) 还是 \(fe\) 直接取 \(\max\) 即可,而奇数位置必然有一半贡献奇数一半贡献偶数,按 \(fo-fe\) 排序后贪心选取即可。
[NOIP2026 模拟 R11] 情书
好神秘啊。
一个定理是,对于一个 \((p+q+1)\)-简并图 \(G\),必然存在点集划分 \((V(A),V(B)),V(A)\cup V(B)=V(G)\) 满足其导出子图 \(A,B\) 分别为 \(p\)-简并图和 \(q\)-简并图。
考虑数学归纳证明。令 \(P(n)\) 为上述结论关于 \(n\) 个点的简并图的情况,假设 \(P(k)\) 成立,考虑证明 \(P(k+1)\),记 \(G\) 为一个 \(k+1\) 点的 \((p+q+1)\)-简并图,找一个度数不超过 \(p+q+1\) 的点 \(v\),那么由 \(P(k)\) 知 \(G\setminus\{v\}\) 存在上述点集划分 \((V(A),V(B))\)。我们记 \(v\) 与 \(A,B\) 的连边数量分别为 \(\alpha,\beta\),则 \(\alpha+\beta\le p+q+1\implies \alpha \le p\lor \beta\le q\),两条件本质等价,假设 \(\alpha\le p\),就划分为 \((A\cup\{v\},B)\),否则划分为 \((A,B\cup\{v\})\) 即可,得证。
由该定理,给定的图可以被划分为两个独立集和两个森林,也就是两个 \(0\)-简并图和两个 \(1\)-简并图。尝试使得 \(V_3,V_4\) 均由链组成,考虑调整:
若存在 \(v\) 在 \(V_3\) 导出子图中度数不小于 \(3\),记其与 \(V_i\) 导出子图的连边数为 \(\gamma_i\),则 \(\gamma_1+\gamma_2+\gamma_4\le 6-\gamma_3\le 3\),若 \(\gamma_1\) 或 \(\gamma_2\) 为 \(0\),将 \(v\) 移过去即可,而若 \(\gamma_4\le 1\) 将 \(v\) 移到 \(V_4\) 同样可行,否则 \(\gamma_1,\gamma_2\ge 1\land \gamma_4\ge 2\implies \gamma_1+\gamma_2+\gamma_3\ge 4\),矛盾,故而必然可以这般调整得到答案。
考虑实现,模拟两个过程即可,对于过程二,每个点只会被调整一次,符合条件。每次只需找度数最小点,开桶或者开优先队列即可。
[NOIP2026 模拟 R11] 2 x 100
容易考虑按 \(\frac{m}{2}\) 分成大数小数,大数之间不能匹配,小数之间随意匹配,显然只需最大化大数与小数之间的匹配即可。二分图匹配,考虑霍尔定理,每个左部点均连向一个前缀的右部点,将左部点降序排序后每次都会选择一个前缀的左部点进行匹配,直接上权值线段树区间加减维护 \(\max |S|-|N(S)|\) 即可,注意记得对 \(0\) 取 \(\max\)。
[必可周赛 R2] 回文 / ABC394E Palindromic Shortest Path 加强版
注:\(n\) 加强到了 \(500\)。
首先容易有一个 \(n^4\),状态开 \((x,y)\) 表示一条 \(x\to y\) 的回文路径最短长度然后同时枚举两侧拓展的端点转移。
正解是 \(O(n^3+26n^2)\),就是你每次只转移一侧,然后额外开个状态表示一侧多了一个字符 \(c\) 的状态,就可以得到这个复杂度。
然后我写的 \(O(\frac{n^4}{w})\)。转移代价都是 \(2\) 所以每个状态只会被更新一次然后对每个 \(x\) 开个 bitset 存尚未更新的 \(y\) 直接做即可。
[必可周赛 R2] 配对 / CF1528B Kavi on Pairing Duty
要么用若干连续等长线段把一个前缀和一个后缀覆盖了然后在中间填剩下的,要么划分成若干独立段,每段用等长线段连续交错覆盖满。后者调和级数 \(O(n\log n)\),前者一个前缀和就 \(O(n)\) 做完了。
[必可周赛 R2] 数组拷贝 / CF1920D Array Repetition
显然序列长超过 \(10^18\) 无意义,故而操作二只会执行 \(O(\log V)\) 次,每次暴力将新增的部分填了然后剩下的对上一长度取模即可。
[必可周赛 R2] 芽 / CF1566E Buds Re-hanging
一个芽只能抵一个叶子,故你考虑先从下到上把所有可能的芽都找出来,这样贪心得到的芽数量 \(cya\) 显然是最多的,特殊地若根也是芽得留着不统计,那么再把过程中为叶子的点数 \(clf\) 统计了(这个算根),答案即为 \(clf-cya\),相当于依次挂到根所在的部分的一个叶子上。
[必可周赛 R2] 海盗 / CF690A2 Collective Mindsets (medium)
显然考虑倒着推,最后两个人必然存活并且都不会得到任何钱,倒数第三个人想存活就要给其中一个人一块钱拉票。摸一下一个简单的思路是每次必然有一半的人如果当前的死了就得不到钱,给他们发钱即可,答案为 \(\lceil\frac{n}{2}\rceil-1\)。然而是错的。
注意到“自己存活”的优先级大于“更多金币”,所以如果当前的人死了某人在此后局面必死,他也会投支持。例如没有金币的时候,三号会给四号投支持,否则三号必死。而 \(n\ge 4\) 时,后四个均会存活,没有死亡威胁就可以给前面的人乱飞,直到 \(n=8\) 必死的人凑齐一半大家又都活了。
摸一下,\(n\) 为奇数时他必须给出 \(\lceil\frac{n}{2}\rceil-1\),他死不死不会影响后面人的死活,不给就飞。而当 \(n\) 为偶数时,记 \(k\) 为最大的 \(2^k\le n\) 的非负整数,答案为 \(\frac{n-2^k}{2}\),粗略归纳这个东西:
\(n=2^k\) 时,显然为 \(0\)。
\(n=2^k+2\) 时,没有硬币他必死,而当有一个硬币时,如果他死了 \(2^k\) 也得死,顺道 \(2^k-1,2^k+1\) 也都活不了,再连锁反应下去,他们一车人都会投赞成,你发现再把这一个硬币给之后某个得不到的人拉一票恰好可行,答案为 \(1\)。
\(n=2^k+4\) 时,硬币 \(\le 1\) 他死了没影响,然后硬币数为 \(2\) 时类似地恰好可行,故答案为 \(2\)。
[必可周赛 R2] 移动棋子 / ARC114D Moving Pieces on Line
显然每个棋子只会往一侧走得到一条线段。
将所有端点值离散化下来给值域分段,然后用各 \(t\) 得到每段需要被覆盖奇数次还是偶数次,用各 \(a\) 统计每个位置的端点个数 \(cnt\)。
从前往后顺序 DP,\(f(i,j)\) 表示考虑到 \([1,i+1)\),若 \(j\) 为正数表示有 \(j\) 段延伸过去,若 \(j\) 为负数表示有 \(j\) 段应从后面过来,一个状态合法仅当 \(|j|\) 与本段需求奇偶性一致。
考虑转移,在本段可以结束之前过来的若干段,是一个后缀 \(\min\),同时还可以增加至多 \(cnt_i\) 段,滑动窗口一下即可,然后再把每个状态加上本段段长 \(|j|\) 倍的代价即可。记段数为 \(m\),答案即为 \(f(m,0)\)。
08.25
[NOIP2026 模拟 R12] Pocky 游戏
容易有一个 \(f(l,r,k,0/1)\) 表示剩余段为 \([l,r]\) 最后一步长 \(k\) 决策方为 \(0/1\) 的答案。注意到 \(k\le \sqrt{2n}\),所以直接做可以做到 \(O(n^2\sqrt n)\)。你注意到可能状态数足够小,精细计算可得 \(O(n^2)\) 的上界,故写一个记搜就做完了。
[NOIP2026 模拟 R12] 宝石装置
边权均关于 \(x\) 单调,可以二分答案,然后只需枚举起点跑最短路判定即可,复杂度 \(O(\log Vnm\log m)\),不好过。考虑优化,把枚举起点的过程挪到二分外面,随机打乱一下,枚举过程中维护前缀答案,到一个点先看他在前缀答案下能不能跑,不能就跳过,能再二分,这样二分次数可以视作随机序列前缀最值个数,是 \(O(\log n)\) 的。复杂度 \(O((n+\log n\log V)m\log m)\)。
[NOIP2026 模拟 R12] 第二个宝石装置
对于每个 \(p_i\),你只保留 \(\ge p_i\) 的数得到新的序列,则这个新的序列中只有至多 \(c\) 个区间满足第 \(c\) 大元素为 \(p_i\),还原到原序列上就是 \(c\) 个 \(l\in[l_1,l_2]\land r\in[r_1,r_2]\) 的限制组,符合限制的区间均满足第 \(c\) 大元素为 \(p_i\),那么这样的限制个数是 \(O(nc)\) 的。容易链表得到。
考虑一个询问 \([L,R]\) 受一个限制组 \([l_1,l_2]\times[r_1,r_2]\) 的贡献,分类讨论可以把这个限制组的贡献变成平面上四个矩形加,扫描线分块平衡一下即可,当然直接写树状数组也能过。复杂度 \(O(nc+q\sqrt n)\) 或者 \(O(nc\log n+q\log n)\)。
[NOIP2026 模拟 R12] 无限队列 / CF1060G Balls and Pockets
首先跳一次相当于执行 \(x\gets x-\sum[a_i\le x]\)。记 \(L\) 为一足够远点,如 \(10^{18}\),关心 \(n\) 个点 \(L\sim L+n-1\),将他们的跳跃过程做成链,一条链跳到某个 \(a_i\) 就结束,你发现它们覆盖了 \([a_1,L+n-1]\) 的所有整点,并且同一深度点为连续一段,因为一个点被吞掉后其右侧点步长比其左侧点步长增多一,会填回空缺。
那么你模拟一遍得到每个查询点所在链与其深度 \(d\),那相当于查询这条链上深度为 \(d-k\) 的点是哪个,再模拟一遍即可。用树状数组维护剩余链就行。
P17315 [KismetOI 2026 I] Gujyo Senpai and Chin-Lan's Game
将美好序列生成过程中被挪动的点称为折点(特殊地,将 \(a_i=i\) 的点也视作折点,显然符合题意),那么 \(1\) 必然在第一个折点处。注意到,对于非折点位置,均满足 \(a_i=i+1\),与其具体在哪一段无关。
可以构造方案使得郡上必然执行 \(n\) 次查询操作。考虑描述“翻了 \(n\) 次才翻到 \(1\)”为“无法提前确认任何点不是 \(1\)”,那么若郡上查询的位置后面还有未知点,这个点必须不是折点,否则其后面的点必然不为 \(1\)。
考虑若这一位置 \(i\) 之后的所有点均已知,如果令这个点为折点,其值可以是多少。你发现它只能是值域上不大于 \(i\) 的最大的未知数,否则他“越过”的那些空位必然不为 \(1\)。
考虑最小化字典序,直接把所有可以为折点的点令作折点即可。
容易做到 \(O(n)\)。
P17316 [KismetOI 2026 I] 孤独绽放的彼岸花
不妨将所有点的点权设为其到根路径边权和,故而所有合法点权局面与原问题形成双射,我们转而对点权局面计数。
考虑原问题合法性限制,事实上就是要求所有点权不超过 \(X\),同时点权在任意根为链首的链上单调不降,即儿子的点权不小于父亲。大可翻转变为父亲的点权不小于儿子,这是一个经典问题,设计 DP \(f(x,i)\) 表示 \(val_x=i\) 的子树内方案数,则 \(f(x)\) 为一个不超过 \(sz_x-1\) 阶的多项式。
证明:考虑数学归纳。首先叶子节点是零阶多项式,对于非叶子节点有转移 \(f(x,k)=\prod_{y\in \mathrm{Son}(x)}s(y,k)\),\(s\) 为 \(f\) 的前缀和,有结论前缀和阶数为原多项式阶数加一,于是可得 \(f(x,k)\) 的阶数不超过 \(\sum_{y\in\mathrm{Son}(x)}sz_y=sz_x-1\)。
于是我们可以拉插得到总合法方案数,值域连续容易做到单次 \(O(n)\) 拉插。接下来我们考虑存在符合条件的走法的方案数。单步容斥,我们考虑不存在深度为 \(k\) 且点权不超过 \(S\) 的点的方案数。
类似地,我们定义 \(g(x,i)\) 表示走到了 \(x\) 点,\(x\) 点权为 \(i\) 且 \(x\) 子树内不存在上述点的方案数。
对于深度不小于 \(k\) 的点,有 \(g(x,i)=0\)。否则,我们钦定根节点点权为 \(X\),有转移:
看起来是一个分段函数,并不是简单多项式。然而,我们大可不关心 \(i<X-S\) 的部分,而直接用 \(f(x)\) 表示他们,只用 \(g(x)\) 维护 \(i\ge X-S\) 段。进行替代之后可得:
我们注意到,在处理完子节点信息后,\(\sum_{i=0}^{X-S-1}f(y,i)\) 可视作一个常数,其值容易在子节点处插值得到,那么我们可以类似地证明 \(g(x)\) 同样是一个阶数不超过 \(sz_x\) 的多项式,于是类似地拉插维护即可。
实现上由于 \(X-S\) 很大,我们需要对 \(g\) 函数进行水平平移,再处理一些平凡的 Corner Case 即可通过本题。
CF1129D Isolation
首先可以对每个点预处理出前后首个相同位置,那么其对左右端点进行一个矩形加贡献,即可得到所有区间恰出现一次的整数个数。
容易有一个 \(O(n^2)\) DP,\(f(i)\) 表示划分到 \(i\) 的合法方案数,转移枚举左端点即可,都枚举了直接开桶可以不带 \(\log\)。
拼合一下,你要求对 \(r\) 动态维护,\([l,r]\) 的代价不超过 \(k\) 的所有 \(l\) 的贡献和。容易考虑用分块维护各 \(l\) 信息来扫描线,对每个块预处理出各值的前缀 \(f\) 和,查询时算上区间加 \(tag\) 求即可,散块直接暴力重构,用 set 之类或者树状数组维护带一个 \(\log\),但不用,直接开个桶同时维护所需前缀和即可,一次修改移动一步显然可以 \(O(1)\) 更新。
08.26
#13142. Cleaning Robots
考虑树形 DP,需要三种状态:根已经有两条连边、根只有一条连边并且必须向上连边、根只有一条连边但是不要求必须再向上连边,转移是容易的。
#17140. Odd Rows
直接 DP,设计 \(f(i,j)\) 表示考虑了前 \(i\) 列有 \(j\) 行当前为奇数是否可行,转移形如一个区间同奇偶或,你 set 维护尚为 \(0\) 的值然后逐个找过去更新并记录转移路径方便输出方案即可。
P13925 [POKATT 2024] 联合猫国 / The Paw-litical Game
显然总节点个数即能合并成一个的区间数是 \(O(n\log n)\) 的,设计 \(f(i)\) 表示考虑到 \(i\) 的最小答案,转移尝试只枚举合法区间,考虑对每个点开一个 vector 存储将其往前合并成一个 \(k'=k+\delta\) 的区间的左端点,关于 \(\delta\) 维护即可,这个 vector 显然可以在转移的时候顺道更新。
P10068 [CCO 2023] Line Town
每个数是否取反只与他所在位置与原位置奇偶性是否一致有关。
将所有数按绝对值降序排序,设计 \(f(i,0/1)\) 表示放了 \(i\) 个数在区间两端,左侧数个数的奇偶性,的最小代价,显然钦定左侧为负数右侧为正数忽略零,转移分别看放左右是否合适即可,若放左侧交换次数就是原序列左侧比他小的元素个数,右侧同理。
如果有相同的值转移顺序可能会有问题,我们考虑将相同的值一并转移,枚举放左侧的点个数 \(i\),将数的正负描述为“在奇数位上为正数”和“在奇数位上为负数”,则所需正负数个数及位置均已知,你显然按顺序匹配,容易得到需要跨越的同值个数,当 \(i\) 变化时,要么正负序列不变,要么互换一对相邻的正负号,同值临项交换贡献变化是平凡的,此外再算上被移动的数左右侧比他小的数个数差即可。
P3269 [JLOI2016] 字符串覆盖
容易字符串哈希得到每个子串的所有出现位置。注意到 \(n\) 奇异小,考虑 \(n!\) 枚举填入顺序,再 \(2^{n-1}\) 枚举每个串是否与前一个串有交,再去做贪心或 DP 状物。
对于最大值,你发现可以直接贪心,如果和上一个有交就放尽可能靠后的位置,否则放尽可能靠前的位置,容易 \(O(nl)\) 预处理一下前后首个匹配位置,做一次复杂度 \(O(n)\)。
对于最小值,你发现不太好贪心,尝试 DP,设计 \(f(i,j)\) 表示在序列上填到 \(i\) 已经填到了第 \(j\) 串的答案,无交显然直接做成子问题,有交你贪心地选最靠前的位置填了即可,做一次复杂度 \(O(nl)\)。
故最终复杂度 \(O(n!2^nnl)\)。
08.27
[NOIP2026 模拟 R13] 相同区间 / #17884. Same Segment
如果没有包含关系是好做的,顺次处理,每次在右端点放一个 \(k\),然后直到首个左端点比这个位置大的区间,再在右端点放一个 \(k\),这样子。那么只需要考虑放 \(0\) 和放 \(k\) 即可。
考虑包含关系,若 \(A\sub B\),则相当于 \(A\) 中有 \(k\)、\(B\setminus A\) 全是 \(0\)。若有多个区间同时被 \(A\) 包含,记其中最小右端点为 \(R\)、最大左端点为 \(L\),若 \(L>R\) 则无解,否则把这些区间全删了替换成 \([L,R]\) 即可,区间内剩余部分全部钦定为 \(0\)。
我们将区间按右端点为第一关键字升序、左端点为第二关键字降序排序,模拟上述过程。注意到被钦定为 \(0\) 的位置不太好处理,我们发现上述过程中,任意剩余区间的左端点必然不被钦定为 \(0\),我们考虑利用这个性质,每次新处理区间时先把它的区间左端点令为其后首个没有被钦定为 \(0\) 的位置即可,容易用 set 维护连续段实现。
最后倒序遍历所有区间,每次在区间左端点放一个 \(k\),然后直到下一个右端点比这个位置小的区间,再在左端点放一个 \(k\),即可。
[NOIP2026 模拟 R13] 锐角多边形 / #12602. Master Zhu and Polygons
显然 \(k\le 3\)。直接算不好,你去算钦定 \(0/1/2/3\) 个锐点的方案数,然后容斥即可。方案数要 \(O(1)\) 算,本质推柿子题。
[NOIP2026 模拟 R13] 2026 / #8917. 2026
和 P9262 一模一样啊。你移到角落上之后就是顺时针或者逆时针转圈,倍增预处理下标映射即可。
[NOIP2026 模拟 R13] 收集积木 / #10245. Zbieranie klocków [B]
首先容易发现完整的 \(2\times 2\) 方格是无法消除的。此外,连接两个 \(2\times 2\) 方格的阶梯状物满足内部所有元素在两个方向均有邻点,也是无法消除的。
记在 \(2\times 2\) 方格内的点为二类点,水平竖直均有邻点的为一类点,剩下的为零类点。考虑统计删不了的个数,首先所有二类点是删不了的,关心上文描述的一类点,你发现其必然形如在对角线上,连续一段完整都是一类点,然后两端各与两个二类点相邻,同时两条对角线至多只会有一条贡献否则会形成 \(2\times 2\) 方格,你开个权值线段树维护每条对角线的一类点区间和、用 set 之类的维护各对角线的二类点二分即可。更新答案直接暴力用新贡献减原贡献就做完了。

浙公网安备 33010602011771号