秋季做题记录

08.31

#8268. Tycho

每个点要么直接走要么等到最近的 \(kp\) 时刻走。你设计 \(f(i)\) 表示走到 \(i\) 等到一个 \(kp\) 的最小代价,转移枚举上一个等到 \(kp\) 时刻的位置,有转移:

\[f(i)\gets f(j)+\left\lceil\frac{a_i-a_j}{p}\right\rceil p+\left\lfloor\frac{a_i-a_j-1}{p}\right\rfloor d \]

把除法取整拆成两元素各自取整的结果加一个按 \(v\bmod p\) 大小关系产生的 \(O(1)\) 的差量,容易权值线段树实现。需要特殊处理一下到终点的贡献因为无需等待

P3059 [USACO12NOV] Concurrently Balanced Strings G

对 \(r\) 扫描线,考虑描述合法的 \(l\)。记 \(s\) 为前缀和,则需 \(s_l=s_r\) 且 \(\forall i\in [l,r],s_l\le s_i\)。对于后者,你对每个 \(l\) 找到首个不符合条件的 \(r\) 即可。对于前者,直接哈希一列的信息即可,开一个 map 计数就做完了。

P5305 [GXOI/GZOI2019] 旧词

一个经典套路是维护每个点与父亲的价值差分,然后 LCA 信息就可以到根链求和、到根链加维护。

#7943. LIS on Grid

考虑 Dilworth 定理。将二维偏序视作反链,则偏序关系为 \(r\le r\lor c\le c\),一条链可以描述为从一个点开始不断向右走或者向上走得到的一条路径,则只需满足原图可以被划分为 \(k\) 条链,充要条件为:

\[\sum\max(0,a_i-k)\le k(n-k) \]

考虑证明必要性。每条链初始显然都在最下面,则每条链至多上升 \(n-k\) 次,总次数即 \(k(n-k)\),故超过该值必然非法。充分性容易按上文构造证明。不妨将不足 \(k\) 的 \(a\) 视作 \(k\) 构造最后任选多出来的删掉即可。

CF193D Two Segments

显然关心值域区间,对 \(r\) 扫描线。考虑对每个 \(l\) 维护什么,实际上只需要维护当前 \([l,r]\) 所分段数即可,因为你插入一个点对段数的影响只与其前后两个元素有关,所以变化量是 \(O(1)\) 的,可以直接区间修改,放上线段树即可。

所求即为段数为 \(1\) 或 \(2\) 的区间数,注意到段数不小于 \(1\),故只需维护最小值和次小值及其个数即可。注意最后减去 \(n\) 个单点。

#5357. 芒果冰加了空气

可以视作删点,不同连通块的点删除顺序无影响。你发现对 \(x\) 的一个儿子 \(y\),\(y\) 删除后其子树不影响,故只关心 \(y\) 子树内有几个与 \(y\) 同连通块的比 \(y\) 先删,容易设计 \(f(i,j)\) 表示 \(i\) 子树中有 \(j\) 个这样的点比 \(i\) 先删的方案数,转移预先做一个前缀和即可类树上背包 \(O(n^2)\)。

#12035. 高维树

你发现一个维度至多作用于一条链。不能复用。故而我们考虑最小化这样的链数,给叶子两两匹配即可。

然而这样并不完备,注意到若两条链无交,二者距离是不正确的,需要钦定所有链有交。考虑找到关于叶子数的带权重心,然后再给不同子树内的叶子两两匹配,如果有奇数个叶子最后一个从根连过去即可,这样所有链交于根,同时链数最小。

P17197 [KOI 2026 #2] 删除局部最小值

考虑对每个点找到两侧首个不小于他的,若没有或与其相等,则当前点删不了;否则,把他们之间的点删完之后,下一轮就删当前点。而他们之间的点,实际上只需要求区间 \(\max\),单调栈处理即可。

考虑区间查询,你发现如果区间不包含两侧首个不小于他的点任一个,这个点就删不了,否则其贡献无变化。故而一个点贡献仅当左右端点与时间各满足一个条件,形如一个三维偏序,直接上 CDQ 即可。

09.01

[MXBZ2026 R1] 双网通行

事实上,距离不超过 \(3\),假定起点为白点:自己距离为 \(0\);邻点和白点点距离为 \(1\);非起点邻点并有白色邻点的黑点距离为 \(2\);剩余黑点距离为 \(3\)。

[MXBZ2026 R1] 栏目排列

将连续段的贡献放在起始位置处理,则前一位为 \(0\) 当前位为 \(1\) 的就能产生 \(1\) 的贡献,容易 \(m^2n\) 预处理出各方法贡献,直接状压 \(f(S,x)\) 表示放了 \(S\) 中的元素最后一个放的 \(x\) 即可,复杂度 \(O(2^mm^2)\)。

[MXBZ2026 R1] 序列消除

进行一次删除后,剩余各段是相互独立的。容易考虑区间 DP 状物,你注意到对于每个右端点 \(r\),有效的左端点只有某个颜色在其之前首次出现的位置以及整个序列开头,因此只有 \(O(nv)\) 个有效区间,故考虑设计 \(f(r,x)\) 表示右端点为 \(r\) 前一个被删的颜色为 \(x\) 的方案数。转移枚举删除颜色 \(y\),要求 \(y\) 出现过,我们只需剥离最右边一段即可,最右边一段的方案数为 \(f(r,y)\),而前面的部分形如“当前右端点颜色已删除,上一个被删除的颜色为 \(y\)”的贡献,不妨再设计一个 \(g(r,x)\) 表示它。

按远近顺序处理各颜色即可。转移 \(f(r,x)\) 时特殊处理删除右端点颜色 \(y\) 的情况,此时 \(f\) 和 \(g\) 的转移是相同的,如果左端点之后仍有颜色 \(y\),系数就是 \(g(la_{r-1}(y),x)f(r-1,y)\),否则就是 \(f(r-1,x)\)。其余情况就只转移 \(f\),系数为 \(g(la_{r}(y),x)f(r,y)\)。复杂度 \(O(nv\log v+nv^2)\)。

考虑区间查询,依旧枚举首次删除的颜色,你发现只有左右两个端点是散的,中间形如一个整段,你对各左端点也跑一遍上述过程,然后中间部分前缀和一下就做完了。查询复杂度 \(O(qv\log V)\),这个 \(\log\) 是逆元。

[MXBZ2026 R1] 停机检查 / #1192. Halting Problem

一个关键观察是,称 \(x=a_i\) 情况下走的边为关键边,则每条关键边只会被走至多一次,否则必然成环,因为走完这条边 \(x\) 是定值,走多次的话情况完全相同。

因此我们只需要对走完每条关键边以及初始情况共 \(n+1\) 种情况,快速求出其走到的下一个关键边,或者走到 \(n+1\),或者走不出去,以及所用步数。非关键边形成的是一个基环树森林,如果一个询问的终点不在环上,容易在树上进行一次搜索处理出来,维护树上到根前缀和 \(dt\),则要求 \(a_y+dt_y=val+dt_x\),开一个 map<vec<int>> 动态维护即可。

考虑在环上的情况,不妨先走到一个钦定的起点,维护走一圈的价值和 \(S\) 与起点到每个点的前缀和 \(s_i\),则第 \(k\) 圈走到第 \(i\) 点时的 \(x=val+kS+s_i\),环上步数为 \(i+km\),\(m\) 为环长。那么走到一个点恰为其 \(a_i\) 所需圈数为 \(k_i=\frac{a_i-s_i-val}{S}\),若 \(k_i<0\lor |S|\nmid a_i-s_i-val\) 则永远走不到。因而要求 \(a_i-s_i\equiv val\pmod {|S|}\),你同样对每个余数 \(r\) 开一个 vec<int> 维护 \(\frac{a_i-s_i-r}{|S|}\),然后对每个 \(val\) 在里面二分首个不小于 \(\frac{val-r}{|S|}\) 的即可。\(|S|=0\) 容易特殊处理。

P17019 [ROI 2026 Day1] 泰莫利亚的调查

也就是选若干条完全不交向上链最大化链长之和。

第一次显然选最长链即可。之后每次,要么选一个新链,要么断开原来链上一条边然后从父亲点向外重新连边。对于前者显然必然从原来链上一个点选一个叶子开始往下连。显然别的方案均不优,否则之前的操作可以调整得更优。

考虑关心选择的链上点,把所有可选点的价值扔到堆里取最大值即可,显然单点总影响量是 \(O(n)\) 的。考虑快速维护一个点更新后的答案,其子节点 \(i\) 贡献形如 \(\max(0,e_i-x)+v_i\),\(e_i\) 为 \(i\) 父边边权,\(v_i\) 为 \(i\) 往下选的答案,那你对每个点开两个堆分别维护 \(e_i+v_i\) 和 \(v_i\) 即可。

09.02

[MXBZ2026 R2] 披萨晚宴 / #18248. Ovenmasters

先把前 \(m\) 个按给定顺序放上,然后给所有桌子按初始权值升序排序,由于插入操作的性质,任何时刻桌子当前的权值在该顺序下均升序。

我们考虑将“\(a\) 必须在 \(b\) 之后放”的限制连边 \(b\to a\) 然后跑拓扑状物,最小化字典序开一个小根堆每次选能选的最小值即可。考虑有哪些连边,先考虑出现过的,首先同一张桌子上的披萨两两相邻连边,若上面的比下面的小显然非法,故而同一张桌子上的所有披萨也是单增的。此外,要求这个披萨不能放到后一张桌子,你在后一张桌子上二分首个比他大的然后连边即可,不存在即非法。

然后考虑不在桌子上的,要求他插入的时刻局面内所有桌子上的披萨都比他大,你在每张桌子上找到首个比他大的连边即可。但这样边数会达到 \(O(n^2)\) 级别。考虑优化,你给不在桌子上的升序排序,然后顺序考虑,假如上一个是 \(i\) 这一个是 \(j\),先处理完 \(i\),然后直接连边 \(i\to j\) 因为要最小化字典序所以没有影响,然后枚举 \((i,j)\) 内的数,把他在桌子上的后一个披萨和 \(j\) 连边,如果没有就非法,这样就是 \(O(n)\) 的了。

最终复杂度 \(O(n\log n)\)。

[MXBZ2026 R2] 分层编辑器 / #13034. Editor

需要对每个加入点找到,他之前最近的激活状态下且等级比他小的点。

我们考虑对每个点维护,若其处于激活状态,左侧最近的激活状态下等级比他小的点。这样加入点 \(i\),先看 \(i-1\) 等级是否比他小,是则直接连边,否则在链上倍增跳即可。

考虑维护这个东西,首先找到 \(i\) 撤销的操作 \(x\),则 \((x,i)\) 中没有等级更小且被激活的点,那么既然 \(x\) 原处于激活状态,\(x-1\) 必然处于激活状态,你从 \(x-1\) 开始倍增跳到首个比 \(i\) 等级小的即可,倍增容易动态维护。

[MXBZ2026 R2] 画布 / #5242. Płótno [B]

关心值域序列,扫描线扫 \(r\),动态维护所有 \(l\) 的连续段个数,然后维护一下区间前 \(k\) 小即可,容易线段树实现。

考虑更新,插入位置对于连续段个数的影响其实只在于其上(或下)、左、右三个邻点原先的存在情况和连通情况,若存在或连通必然是在一个前缀左端点,故而可以做成常数次区间加。

存在是平凡的,考虑判定连通。形如对每一个右端点 \(r\),常数次询问,每次给定两个点,问使他们连通的最大左端点。你发现行数只有 \(2\),破环成链,相当于查询一个区间左右端点连通的最大左端点值,你对每个区间维护左端点上、下和右端点上、下四种情况的答案,合并直接 \(O(2^3)\) 枚举两个区间的端点情况,要求中间拼合部分一致,容易线段树实现。

[MXBZ2026 R2] 快速旋转 / #9963. Express Rotations

按值域从大到小考虑。显然如果队首是最大值能删就删不劣,否则要转动序列,那显然只会往左走一段再往右走,或往右走一段再往左走,其余的方案是不优的。

对于值 \(v\),设其所有位置为 \(p_1\sim p_m\),我们考虑对每个 \(p_i\) 维护出 \(v\) 最后一个删的位置为 \(p_i\) 的最小代价 \(f_e(i)\),那么首次转到 \(p_i\) 的最小代价容易由 \(v+1\) 的 \(f_e\) 单调队列得到,记作 \(f_b(i)\)。

破环成链,用 BIT 动态维护仍在序列上的位置区间和,我们预先将 \(v\) 的部分删去,对每个 \(v\) 位置存储其后一段的价值,前缀和为 \(s\),那么从 \(i\) 开始到 \(j\) 结束的两种走法代价分别为:

\[f_b(i)+s(i-1)-s(j)+s(j+m-1)-s(j)+(i-j-1)v\\ f_b(i)+s(j+m-2)-s(i-1)+s(j+m-2)-s(j-1)+(i-j)v \]

容易分离 \(i,j\),那么每个 \(j\) 只需要选取 \((j,j+m)\) 内的 \(i\) 的最小代价即可,再写两个单调队列就做完了。

P14284 [ICPC 2025 WF] Delivery Service

显然考虑把每个点拆成两个状态然后直接并查集,但显然会算重。

我们不妨记 \(S_i\) 为连通块 \(i\) 内的去重后点集,可以直接启发式合并,那么答案的一部分是 \(\sum_i{|S_i|\choose 2}\)。但还是会算重,存在一对点在两个不同连通块连通两次的情况,也就是要减去 \(\sum_{i<j}{|S_i\cap S_j|\choose 2}\)。

考虑如何维护后者,你考虑一个点只会出现两次,因此交集大小之和是 \(O(n)\) 的,同时一个集合与其他集合的交集大小之和不超过集合内元素个数,你暴力地维护三元组 \((i,j,c)\) 表示 \(S_i\cap S_j=c\),考虑合并 \(S_i\gets S_j\),对于 \((i,k,c_i)\) 和 \((j,k,c_j)\),你发现合并之后就是 \((i,k,c_i+c_j)\),因为一个元素不可能出现三次。\(i\) 没有的 \((k,c)\) 直接转接给 \(i\) 即可,\(k=j\) 就直接删了。

09.03

CF547D Mike and Fish

容易把网格图转为二分图,将红色视为行连列,蓝色视为列连行,则要求给边定向使得所有点入度与出度之差不超过 \(1\),你对每个连通块去找一条欧拉路径即可。

但并不完善,因为存在欧拉路径仅当图中度数为奇数的点不超过 \(2\) 个。注意到度数为奇数的点必然有偶数个,直接将他们和一个虚点连边即可,这样所有点度数均为偶数,然后跑欧拉回路就行了,欧拉回路中每个点出入度相等,把连向虚点的边去掉仍满足度数差不超过 \(1\)。

P15869 【MX-X26-T5】「Cfz Round 7」anybody can finds love (expect you)

首先是否存在欧拉回路是好判的,考虑保证重边不相邻出现,你尝试给每个点的所有边两两配对满足配对边邻点不同,只要不存在绝对众数即可。

给配对的边放一组,那么每组的边都形成一个环。你考虑合并一个交点的两个环,设其在两环上的边分别为 \(a\ne b,c\ne d\),则 \(a\ne c\land b\ne d\) 和 \(a\ne d\land b\ne c\) 必然有一个成立,选成立的一种方案直接插入即可,容易用链表维护序列。

AGC018F Two Trees

一个关键性质是,由于子树和为 \(\pm1\) 均为奇数,故有解的一个必要条件是每个点在两棵子树内的儿子数量奇偶性相同。不妨给两个根连一条边,那么就可以转化为度数的奇偶性。

然后一个非常神仙的构造是,你将度数为奇数的点在两棵树中的对应点连非树边,得到一个所有度数均为偶数的图,跑欧拉回路,原偶数度数节点权值设做 \(0\),否则若非树边从 A 到 B 就设做 \(1\),从 B 到 A 就设做 \(-1\)。

考虑证明,你将欧拉回路拆分成若干简单环,对于一个点 \(x\),不妨考察 A 树,若一个环在 A 树上的部分完全在其子树内,则一去一回两条非树边的权值抵消了。否则,若一个环经过了 \(x\) 的父边,则会给 \(x\) 贡献 \(\pm 1\),同时由于父边只能被经过一次,这样的贡献必然只有一次,故符合条件。

对于根节点,我们去掉之前额外连的那条边,将之替换为一个虚根作为两个根节点的父亲,因而两个根同样符合条件,而虚根的权值无需在意,故符合条件。

P3275 [SCOI2011] 糖果

差分约束板子。你直接 SPFA 跑最长路,加一个入队次数超过 \(2e7\) 就退出,可以卡过。考虑正解,注意到边权只有 \(0/1\),你先把为 \(0\) 的连了跑一遍 tarjan,则每个 SCC 内部权值相同,然后再连为 \(1\) 的边拓扑做即可。

P11095 [ROI 2021] 旅行 (Day 2)

升序枚举边权 \(v\),则路径最大值已知,考虑加入边权为 \(v\) 的边。考虑当前局面,对于每个环,无论起点终点是什么都可以贡献其中最小边权,可以直接缩点,剩余部分形如一棵树。

那么有几种情况,如果在一个边双内部,没有作用;产生了一个新的边双,可以直接暴力缩点,同时更新其中的答案,总合并次数在 \(O(n)\);连通了两个连通块,貌似有点繁琐,考虑可以预先把 MST 跑出来,然后在上面更新信息。

具体地,我们对 MST 维护两个信息:到根路径最小值以及答案。路径最小值是容易更新的,你产生新边双时统计其中新的最小边权,然后对边双内深度最小的点进行子树更新即可;更新答案时,我们假定树上所有边均已加入,则同样只需考虑产生新边双的影响,那么有贡献仅当最小值为边双内最值,否则加入当前边没有作用,故而可以直接用边双内最小值加上当前边权更新子树答案,然后当每个点首次与根连通时刷新单点信息即可。

P4630 [APIO2018] 铁人两项

考虑描述一组合法三元组。首先三者必须连通,其次不存在点 \(x\),使得删除 \(x\) 后,\(s,f\) 同时与 \(c\) 不连通。你发现这是充要的。

考虑建出圆方树,枚举 \(c\) 所在圆点,第一种是 \(s,f\) 来自 \(c\) 的不同子树,容易处理,第二种是 \(s,f\) 在同一个点双的不同点交汇,然后走到 \(c\),则 \(c\) 必须为点双上点,可以转而枚举交汇点双方点做。

P6378 [PA 2010] Riddle

2-sat 板子,对于一个部分的限制你做一个前后缀虚点优化即可实现至多选一个,至少选一个的限制无需考虑,因为如果有部分没有选局面合法,你随便选一个局面仍合法。

P5332 [JSOI2019] 精准预测

首先肯定有一个暴力做法,你把 \(2nT\) 个状态全部建出来然后跑 2-sat,同一个人,之前死了后面就一直死,后面活着之前就一直活,然后给定的预测是平凡的,记得反情况要连反边,查询的话你就看 \(i\) 在 \(T+1\) 时刻活着会导致几个人在 \(T+1\) 时刻必死,特别的若会推出自己必死那 \(i\) 就必死,自己答案为 \(0\) 并且其他所有点要算上 \(i\) 的贡献。

考虑把时间轴压缩掉。各个操作均只在当前时刻有效,那么对于一次操作,我们只显式激活这次操作的两个点各自相关的时刻即可,这样点数就在 \(O(n+m)\)。

考虑求答案,你发现是个 DAG 可达性计数,直接 bitset 空间爆了,但不 bitset 不太可能,于是给目标点分块就好了。记块长为 \(B\),消耗空间在 \(4(n+m)\frac{B}{8}\text{byte}\),时间复杂度为 \(O(\frac{(n+m)^2}{B}+(n+m)\frac{n}{w})\),取 \(B=10^4\) 即可。

09.04

#10706. Red-Blue MST

首先容易先对红蓝边分别跑一棵 MST 出来,则不在 MST 上的边必然没用。

剩下的红边有两种,一种是必须加,这个也容易处理出来,后文忽略掉,考虑另一种,他要加入就要替换掉原来的一条蓝边。

考虑一个选定的红边边集,求他产生的生成树。我们先得到蓝边的 MST,然后按边权升序枚举红边,选定路径上最大的剩余蓝边替换。这个过程还可以表示为,将蓝边和红边分别升序排序,那么对一条红边 \((u,v)\),我们考虑描述他替换掉的蓝边,先将他之前的红边全部加入,然后找到首个蓝边前缀使得 \(u,v\) 连通,那条边就是他替换掉的,显然每个红边对应的蓝边均不同,容易反证,有两条红边“删掉这条蓝边两端点就不连通”,然而边权更小的红边相当于顶替了这条蓝边,因此边权更大的红边删掉这条蓝边没有影响,矛盾。

那么,在我们贪心地升序选红边的过程中,每个红边对应的蓝边是一定的,否则不优。考虑反证,假如这条红边对应蓝边发生变化,显然只会边权变得更大,那么这条蓝边原先必然对应了边权更小的另一条红边,把它调整过来不劣。

因此存在一个暴力是对每条红边去二分他对应的蓝边。这个过程是可以整体二分的,我们先把 \([1,mid]\) 的蓝边升序加入,然后再升序尝试加入当前的所有红边,那么在树上的红边他替换掉的蓝边就在 \((mid,r]\) 内,将这些红边记作 \(Q_r\),不在树上的红边他替换掉的蓝边就在 \([l,mid]\) 内,将这些红边记作 \(Q_l\)。

对于 \(Q_r\) 中的红边,你本应关心 \(Q_l\) 中边权比他小的边,然而你加入他之前的红边之后,他的两个端点仍不连通,而 \(Q_l\) 中的红边两个端点在加入 \([1,mid]\) 的蓝边后已经连通了,所以加不加 \(Q_l\) 中的红边对 \(Q_r\) 中的边端点连通性判定无影响,于是可以不管。

对于 \(Q_l\) 中的红边,你本应关心 \(Q_r\) 中边权比他小的边,然而 \(Q_r\) 中边权比他大的边的两个端点,在处理这条红边的时刻尚未连通,而这条红边的两个端点在当时已经连通了,因此加入这类边对这条红边端点连通性判定无影响,于是我们可以在向左递归之前直接把 \(Q_r\) 中的所有红边先加入。

P6643 [CCO 2020] Mountains and Valleys

如果不走非树边,代价就是 \(2(n-1)-\mathrm{diam}\)。假如走一条非树边,记其端点为 \(u,v\),边权为 \(w\),若起点和终点分别为 \(s,t\),代价为:

\[2(n-1)-\mathrm{dis}(s,t)-\mathrm{dis}(u,v)+w+2\max(0,|\mathrm{path}(s,t)\cap \mathrm{path}(u,v)|-1) \]

而你走一条非树边,就要求其树上路径长度超过边权,则 \(\mathrm{diam}>\frac{n}{3}\),那你倘若走两条非树边,因为每个点至少被经过一次,代价大于 \(n-3+\frac{2}{3}n=\frac{5}{3}n-3\),而你不走非树边的代价不大于 \(\frac{5}{3}n-2\),你发现不劣,因此非树边只会走至多一条。

\(\max\) 很不好看,我们分讨有交无交两种情况把他拆了。枚举 \((u,v,w)\),则我们要求最大的 \(\mathrm{dis}(s,t)-2|\mathrm{path}(s,t)\cap \mathrm{path}(u,v)|\),相当于给 \(u,v\) 路径上的边权设做 \(-1\) 然后求直径,于是有一个 \(O(nm)\) 的做法。

考虑点分治,你只处理经过分治中心的 \((u,v,w)\)。你对每个点处理出,假设他到分治中心的路径边权为 \(-1\),在他所在分治中心儿子子树中选一条向上链、一整条链有交或无交的答案,显然是可以 \(O(n)\) 做的。注意到块大小不超过 \(\frac{n}{3}\) 无需考虑,故只会计算不超过 \(3\) 次。然后就能做到理论 \(O(n+m)\)。

#7980. 区间切割

先考虑全局操作。倘若 \(x\) 为随机排列,则每个区间期望被操作 \(O(\log n)\) 次,我们只需考虑快速找出影响各个区间的操作即可。我们记录下每个点的操作时刻,枚举区间,每次取区间 \(\min\) 位置的操作即可。

倘若 \(x\) 非随机排列呢。非常牛地,我们将一个区间三等分为 \(l,ml,mr,r\),则落在 \([l,ml)\cup(mr,r]\) 内的操作,必然只会修改自己一侧的端点,于是我们可以只关心落在 \([ml,mr]\) 内的操作,这样每次区间长度减为 \(\frac{1}{3}\),也只会执行 \(\log n\) 次。需要查询 \([l,ml)\) 中最大的 \(t\) 小于某时刻的点,线段树上二分即可,右侧同理。

考虑非全局操作,我们扫描线维护每个点的 \(t\) 即可。

09.05

P10357 [PA 2024] Żelki

每种颜色购买数量相同,你考虑每轮每种选一个,然后选若干轮即可。容易 \(O(nm)\) 背包出一轮后各余数的最小花费,然后跑一个同余最短路,\(|V|=m,|E|=nm\),你跑不带堆优化的 dijkstra 即可做到 \(O(m^2+nm)\)。

P13534 [OOI 2023] The way home / 回家的路

你考虑在一条路径上,你必然只会在各个前缀最大值处表演。因此考虑只关心各前缀最大值,先 \(O(n^3)\) 预处理出两两距离,然后你发现你需要关心到这里的操作次数和当前剩余量。你考虑,如果可以不表演直接到这里,那不表演显然不劣,否则剩余量必然小于上一次表演的 \(w\),而上一次表演的 \(w\) 比当前 \(w\) 更小,因此你在这里额外表演一次是不劣的,故而你只需对每个点跑出最小表演次数,在此基础上再去最大化剩余量即可。

AGC034D Manhattan Max Matching

容易考虑二分图跑费用流,但直接建模边数在 \(O(n^2)\) 很不好过。你考虑曼哈顿距离两个绝对值都是可以拆的,拆出来四种情况,你开四个虚点表示,然后将 \(2n\) 个点和这四个虚点连边即可,然后直接费用流就过了。

AGC056C 01 Balanced

考虑前缀和后差分约束,但是直接做有点炸。考虑将 \(0\) 视作 \(-1\),这样区间 \(0,1\) 相等可以视作 \(s_r=s_{l-1}\),可以直接合并,约束相邻点只能做到约束差绝对值不超过 \(1\),然而不会出现差为 \(0\) 的情况,因为你合并的两个点必然同奇偶,合并完相邻点连边只会在奇偶点之间,也就是二分图,边权又都是 \(1\),因而两侧距离奇偶性必然不同,不会相等。最小化字典序从 \(0\) 开始跑最长路即可。

ARC076F Exhausted?

显然是要求人和椅子的最大匹配。考虑霍尔定理,对于一个左部点集合 \(S\),\(|N(S)|\) 即为 \(\min(m,\max_{i\in S}l_i+m-\min_{i\in S}r_i+1)\)。我们将所有左部点按 \(l\) 升序排序然后扫描线,则 \(\max l_i\) 已知,我们希望选若干点并对一个点数尽可能最大化 \(\min r_i\),对 \(r\) 开一个权值线段树即可。

CF1361E James and the Chase

先随便找到一个好点,然后拉出一棵 DFS 树,若一个点子树内有两个返祖边它必然不是好点,否则它是好点当且仅当那条返祖边指向的点是好点。找初始好点的话直接随几个就行,随不到就当好点数量不够。

P13592 [NWRRC 2023] Loops

对一个环,我们将其 \(6\) 条偏序关系连出来,你发现必然存在一对对边同向,那么必然存在摆放方案,使得每个点先向右连边,同时第一列上的点向下连边。你这么连出来,然后逐个确定剩下的边,你发现必然不会成环,故而直接跑拓扑即可。

P11812 [PA 2015] 精确打击 / Kontrmanifestacja

见微近做题记录。

09.07

P13358 [GDCPC 2024] 小班课

容易考虑一个拆点然后是一个匹配状物。但是每个学生有一个意向度排列。有一个想法是,若一个学生当前意向度最高的课程不是他的最终匹配,那你大可以把他往后放,直到他意向度最高的课程恰为他的匹配,就给他放上。

这样能构造方案当且仅当,没有两个点匹配出顺序交错的情况。直接调整并不好做,你考虑只关心每个时刻当前点 \(x\) 意向最高的有余量的课程,若其的一个匹配点是 \(y\),我们连边 \(x\to y\),这样能得到一棵基环树,那么环上的点必然可以匹配上自己意向最高的点,就可以先把环上的点做掉,然后就是子问题。因此答案是可以直接取到最大匹配的,显然这是上界。

2061G - Kevin and Teams

先考虑如何确定 \(k\)。你考虑对于一个已知匹配的图,你把所有已匹配点连成完全图显然是不劣的,这样在补图中他们之间没有边。那剩下的未匹配点呢,你选一个加入之前的团,剩下的不连边,感性理解这样不劣。

记原图匹配点数为 \(x\),则团大小为 \(2x+1\),易知反图最大匹配为 \(\min(n-2x-1,2x+1+\max(0,\lfloor\frac{n-4x-2}{2}\rfloor))\)。对一个大小为 \(3k+1\) 的图,你直接取 \(x=k\) 即可达到 \(k\) 的答案,感性理解这样两侧答案均衡最优。由此推得,一个 \(n\) 个点的图答案为 \(\lfloor\frac{n+1}{3}\rfloor\)。

考虑查询 \(n\) 次并构造。你考虑维护一个同色的链,用链尾和一个新点查询,若同色就加入链,否则你就把链尾和链尾前一个、链尾和这个新点分别加入两个匹配,同时删除链尾和链尾前一个点。这样消耗三个点即可兑成一组匹配,最后链还有剩得就贪心匹配加入即可。

AGC036D Negative Cycle

考虑差分约束。初始 \(n-1\) 条边即可描述为 \(a_i\ge a_{i+1}\)。

对一条 \(x\to y\) 的负边,含义为 \(a_y\le a_x-1\),那么若其保留,则对于 \(x'\le x,y'\ge y\) 的所有 \(x'\to y'\) 均可以保留。同理,对一条 \(y\to x\) 的正边,含义为 \(a_x\le a_y+1\),则对于 \(x\le x'<y'\le y\) 的所有 \(y'\to x'\) 均可以保留。

你注意到约束下差分值是很小的,我们转而关心 \(\delta_i=a_{i-1}-a_i\),则 \(\delta_i\ge 0\),\(x\to y\) 约束写作 \(\sum_{i=x+1}^y\delta_i\ge 1\),\(y\to x\) 约束写作 \(\sum_{i=x+1}^y\delta_i\le 1\)。那么显然钦定 \(\delta_i\in\{0,1\}\) 即可。

对保留情况构造序列很不好做,我们转而对序列求最大保留价值。首先完全被包含在 \(0\) 连通块内的负边均需删除,然后跨越了两个 \(1\) 的正边亦需删除。因此我们只需对每个右端点关心前两个 \(1\) 的位置即可,容易 \(O(n^3)\) DP。

#7872. 崩坏天际线

我们考虑计算 \([l,r]\to [x,y]\) 的概率,首先 \([x,y]\) 内部不得有崩坏操作。否则,你考虑 \((l,x]\) 中所有的时间后缀 \(\max\) 位置,他们均需选择右侧,\([y,r)\) 中同理。

那么容易离线下来,倒序处理,操作二更新单点信息,操作一建一个笛卡尔树然后直接计算答案,复杂度 \(O(n^2)\),\(8\) 秒优势在我。

P16997 【MX-S15-T3】「DLESS-5」旅游定价

显然所求为 \(n\max\{\sum p+\sum q\}\)。

考虑固定 \(q\),则 \(p_i=\min_j|x_i-a_j|-q_j\)。将之一般化,设 \(f(x)=\min_j|x-a_j|-q_j\),则 \(p_i=\max_{x\in S_i}f(x)\)。

尝试发掘 \(f\) 的性质,注意到对于一个 \(j\) 是一个绝对值加一个常数,你把图像画出来,则一个 \(j\) 若有作用范围,必然为一段连续区间,同时你关心峰值 \(x=a_j\),你发现其必然由 \(j\) 作用得到,否则你增大 \(q_j\) 不劣。也就是说,\(f(a_j)=-q_j\),则所求即为 \(\sum_i \max_{x\in S_i}f(x)-\sum_j f(a_j)\)。

\(f\) 函数限制还是太多了,非常牛地,我们考虑直接把他放缩掉。我们考虑求一个 \(g(x)\) 满足 \(f(a_j)=g(a_j)\land g(x)\le f(x)\),那么可以直接转而求 \(\max_g\sum_i\max_{x\in S_i} g(x)-\sum_jg(a_j)\)。之所以如此,是因为 \(g\) 函数的限制可以直接写作 \(|g(i)-g(i-1)|\le 1\),这样令 \(f(a_j)\gets g(a_j)\) 后必然有 \(f(x)\ge g(x)\)。

转而关心 \(\delta(i)=g(i)-g(i-1)\in\{-1,0,1\}\),将 \(g\) 的贡献拆到 \(\delta\) 上,假定我们已然确定了 \(x\),则 \(\delta(k)\) 的转移系数为 \(\alpha_k=\sum[x_i\ge k]-\sum[a_j\ge k]\)。既然我们要求最大值,那么让 \(\alpha_k\delta(k)\gets |\alpha_k|\) 即可,故可以钦定 \(\delta(i)\in\{-1,1\}\)。

我们发现我们还没有使用 \(k\le 15\) 的性质。直接状压前 \(k+1\) 位 \(\delta\) 的正负,然后就能直接算 \(\max_{x\in S_i}g(x)\) 了。复杂度 \(O(nk2^k)\)。

P16309 [ICPC 2023 Jinan R] 图划分 2

容易有一个 \(f(i,j)\) 表示子树 \(i\) 根保留大小 \(j\) 的方案数,转移类树上背包 \(O(n^2)\)。

你注意到有效状态数看上去不多,分析一下。若子树大小小于 \(k\) 必须整个保留,否则至多有 \(n\bmod k\) 个有效状态,而若 \(k\ge \sqrt n\),你考虑子树至多割 \(\frac{siz}{k}\) 次,因而余数实际上也只有不超过 \(\frac{n}{k}\) 种。因此分析下来一个点的状态数在 \(O(\sqrt n)\),树上背包分析出复杂度为 \(O(n\sqrt n)\)。

其实可以优化。你考虑子树大小不超过 \(k\) 的可以全部跳过,同时一个点转移只需考虑子树大小至少为 \(k\) 的儿子,有至少两个大小不小于 \(k\) 的儿子的大小不小于 \(k\) 的儿子数之和是 \(O(\frac{n}{k})\)。因而你直接 NTT 开卷即可做到 \(O(n/k\cdot k\log k)=O(n\log n)\)。更近一步地,我们用暴力枚举有效状态替换 NTT 即可做到 \(O(n)\),分析不动了。

09.08

CF1844G Tree Weights

我们将距离描述为 \(dp_u+dp_v-2dp_{\mathrm{lca}(u,v)}\),则 \(dp_{i+1}=d_i-dp_i+2dp_{\mathrm{lca}(u,v)}\)。推不出什么柿子,感觉只能大力高消。

然后有一个非常牛的 trick。你考虑求各 \(dp_i\bmod 2\) 的值,那么未知量 \(dp_{\mathrm{lca}(i,i+1)}\) 因为前面 \(2\) 的系数就直接消掉了。然后你求 \(dp_i\bmod 4\) 的值,则 \(dp_{i+1}\equiv d_i-dp_i+2(dp_{\mathrm{lca}(i,i+1)}\bmod 2)\pmod 4\),你发现都是已知量。然后你一直做到 \(2^{60}\) 即可。这么牛。

CF1458F Range Diameter Sum

严肃学习树上圆。

考虑分治,对 \([l,m]\) 中的 \(i\) 维护 \([i,m]\) 的邻域信息,对 \((m,r]\) 的 \(i\) 维护 \((m,i]\) 的邻域信息。记 \(i\) 维护的邻域为 \(S_i\),则对于左侧的 \(i\),有 \(S_i\supe S_{i+1}\),对右侧的 \(i\) 有 \(S_i\sube S_{i+1}\)。

因此合并时,你双指针,对每个左侧的 \(i\) 右侧的邻域必然满足,一个前缀被 \(S_i\) 包含,一个后缀包含 \(S_i\),中间有一段与其无后缀关系,显然随 \(i\) 右移这两个指针均单调左移。

那么现在我们需要快速求出,一个点与一个区间内的邻域中心的距离之和,写一个点分树即可。

#837. Giant Penguin

首先 \(m=n-1\) 是平凡的,点分树就行。考虑一般情况。考虑 \(k\) 很小的作用,你发现如果跑一个生成树,那么一个点的各子树之间额外连边不超过 \(k\) 条。暴力地,我们对这 \(O(k)\) 个端点跑一遍 BFS,计算答案时枚举点取最小值即可,算重不影响答案。

CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

考虑描述 DK 串,显然只需满足只有至多一种字符出现了奇数次即可。字符只有 \(22\) 个。考虑状压,一个子树内向上的链个数只有子树大小个,考虑 dsu on tree,合并时你考虑对轻儿子内的所有存在状态,去枚举异或哪一位,然后统计答案,复杂度 \(O(nv\log n)\)。

#6536. 收缩的树

见平凡做题记录(CF1060F)。

P10789 [NOI2024] 登山

注意到有 \(h\ge 0\),因而你向上冲刺一次后,必然会更新上限。所以行程形如,跳到某个点并更新限制,然后下滑到某一点沿途再把限制上提,然后再往上跳,跳到的深度是单减的。故直接设计 \(f(x)\) 表示 \(x\to 1\) 的方案,重定义 \(l,r\) 为能跳到的深度范围,有转移:

\[f(x)=\sum_{u\in\mathrm{sub}_x}\sum_{v\in\mathrm{anc}_x}\left[l_u \le dp_v\le \min\{r_u,\min_{i\in \mathrm{path}(u,x)}lim_i\}\right]f(v) \]

从浅到深 DP,但你这个子树转移限制从浅到深很不好维护,考虑从深到浅维护,然后再逐步撤销。考虑 dsu on tree,只维护重链祖先链,那么每个点的贡献相当于一个区间和,做差分就是两个单点加,做完一个点 \(x\) 的子树后要对所有区间右端点对 \(lim_x\) 取 \(\min\),可以直接做成均摊 \(O(1)\) 的单点修改。注意到只有单点操作故而维护答案是容易的,可以直接用一个 map 维护,复杂度 \(O(n\log^2 n)\)。

09.09

P16957 [SCCPC 2026] 那一年的秘密基地

先考虑序列一定时,对每个根求答案。

若根一定,顺序扫描序列,则只需查询子树中有多少元素是之前出现过的,对 DFS 序建 BIT 即可。考虑求所有根的答案,仍顺序扫描序列,你去枚举根所在子树,然后就是一个子树加,再建一棵线段树存答案即可。

考虑修改。只交换相邻两项,则其他点本身不受影响,二者间的答案不受影响,对两个子树修改即可。

P16452 [APIO 2026] APIOBike

你考虑策略必然形如,选一个起点,子树中所有点均 \(a_i=b_i\) 的无需进入,然后走一路就拿一路,在最后一次经过某点时再放回去。那么只需考虑关键点的导出子图状物,剩下的部分删去即可。

感觉答案上界会是 \(2(n-1)\),尝试证明。你考虑走到一个点,先走进 \(\sum a\ge \sum b\) 的,再走进 \(\sum a<\sum b\) 的,归纳证明,假设 \(\sum a\ge\sum b\) 的子树都可以遍历一圈并回溯使得符合条件,初始子树有 \(\sum a=\sum b\),先把 \(\sum a\ge \sum b\) 的子树全部处理掉,那么走进任意 \(\sum a\le \sum b\) 的子树时,车上剩的元素个数必然不小于 \(\sum b-\sum a\),故而可以全填到子树根上使其符合条件,而叶子显然合法,故得证。

那感觉答案会形如 \(2(n-1)-\mathrm{diam}\) 状物,假如这条路径起始点为 \(S,T\),则以 \(T\) 为根 \(S\) 往上所有子树均需满足 \(\sum a\ge \sum b\),因为无法从父亲补充。但这样不一定优秀,你考虑可能走到某个祖先之后再往回绕回来,更进一步地这个祖先必然是首个 \(\sum a\ge \sum b\) 的祖先。

那么答案就形如,选出这样一条链,其他边都走两遍,链上 \(\sum a\ge \sum b\) 的走一遍,\(\sum a< \sum b\) 的走三遍,也就是前者边权为 \(+1\) 后者边权为 \(-1\) 求最大长度,钦定树根为链尾。那我们跑一个换根 DP 即可。

构造方案是平凡的,从链头开始,若当前 \(\sum a\ge \sum b\) 就模拟上述过程再往后走,否则先往后走,等回溯回来再模拟上述过程即可。

P16435 [APIO 2026 中国赛区] 集宝

考虑树上圆理论。考虑查询区间 \([l,r]\) 内的相邻点 \(x,x+1\),若 \(x,x+1\) 的树上圆无交,则 \([x+1,r]\) 部分的路径是一定的,与 \(l\) 无关。而若 \(x,x+1\) 的树上圆有交,则可以直接缩合成交集部分,你显然要从之前某个点走到交集内。

你考虑对于每个区间,维护区间内第一个圆和他到第二个圆要走到的当前圆边界上的点,同理维护最后一个圆,再维护区间内圆之间的额外代价,然后就能区间合并,写一个倍增即可。注意特判区间内只有一个圆的情况。

09.10

CF1442E Black, White and Grey Tree

写过。

CF1712F Triameter

记 \(h(x)\) 为 \(x\) 到最近的叶子节点的距离,则 \(x,y\) 的最短路为 \(\min\{\mathrm{dis}(x,y),h(x)+h(y)+X\}\)。我们将所有点按 \(h\) 升序排序,对一次询问,我们二分答案,然后双指针,对于一个 \(x\),满足 \(h(y)+X\ge ans-h(x)\) 的必然为一个后缀,只需关心当前点到该后缀内的最长距离,维护该后缀的直径即可。

你发现不用二分,来一个答案指针不断尝试答案增大即可,于是即可做到 \(O(nq)\)。

ARC087F Squirrel Migration

\(\mathrm{dis}(x,y)=dp_x+dp_y-dp_{\mathrm{lca}(x,y)}\),因为是排列所以前两项之和是定值,我们只需考虑最小化 \(\sum dp_{\mathrm{lca}(i,p_i)}\) 即可。注意到你以重心为根可以使所有对的 \(dp_{\mathrm{lca}}=0\) 显然最优,问题变为要使得每个 \(p_x\) 与 \(x\) 不在同一子树中。

考虑容斥,钦定一个 \(p_x\) 和 \(x\) 同子树相当于少了一个选点,你跑一个背包把所有带系数自由选点点数的方案给求出来,那么 \(k\) 个点的方案显然就是 \(k!\)。

P13695 [CEOI 2025] theseus

容易考虑先跑出最短路树。先不管非树边,考虑如何区分出父边。一条边的边权在其两个端点的意义是相反的,考虑找到另一个相反的信息给他们异或起来,显然考虑二者标号大小关系即可。

再考虑非树的情况。如果二者不同层显然让深度大的走到深度小的,考虑同层之间的移动,我们需要将这类移动次数限定在 \(C=O(\log n)\) 次以内。先考虑如何不走出环,移动策略必须一定,不妨钦定多条父边走对方标号最大的一条,将同层点按标号升序排序,对同层连边钦定右侧点为左侧点父亲即可,这样额外步数在 \(O(n)\)。

考虑优化。考虑 \(\log\) 意义,神秘地,考虑启发式合并,对同层点,我们让大小小的走到大小大的。具体地,我们将边挂在深度更深的点或同深度编号更大的点处理,对于每个点,降序枚举他的邻边,若对方深度比他小就走过去,将对方大小加上自己大小并把自己大小清空,否则让对方走过来并同理处理。这样他走到的第一条出边,若深度不同则大小不降,若深度相同则大小增倍,于是额外步数在 \(O(\log n)\)。

P11946 [KTSC 2025] 信竞天择 2 / evolution

显然考虑对每个子树维护子树内相对大小,然后不断合并子树。

容易考虑一个二分插入的做法,结合启发式合并操作次数可以做到 \(O(n\log^2 n)\)。

然而我们的限制形如与 \({a+b\choose a}\) 相关,当 \(a,b\) 差距很大的时候就很炸。考虑优化,注意到因为 \(a\) 序列本就有序,每次在全局二分是很不优的,比如全都挤在开头的情况。那你考虑给 \(b\) 分个块,逐块地去跳,一次合并次数大致在 \(O(a\log B+\frac{b}{B}+a)\)。考虑尽量给 \(B\) 取到 \(2\) 的次幂,这样二分次数不变块长尽可能小。

考虑枚举 \(B=2^k\) 取最优值。但这样还是会被卡,仍需优化。首先不妨每次让最小的子树合并到最大的子树内,二分的时候将下界与上一次二分的结果取较大值,其次你发现你在找 \(k\) 的时候写小于会挂 #30,写小于等于会挂 #29,所以取等的时候以一定概率随机更新即可(雾)。

09.11

[MXBZ2026 R3] 旋转

先算出每个时钟的需求,因为是区间加所以我们做一个差分,然后形如要做匹配之类的,需要严肃反贪。

不想想太多怎么办,设计 \(f(i,j)\) 表示考虑到 \(i\) 有 \(j\) 个线段可以延伸到后面的最小代价,\(j\) 开 \(128\) 就能飞过去了,更小也许也可以。嘟嘟嘟。

被卡了,首先第二维可以变成“有 \(4j\) 条线段”,然后我们第二维直接开到 \(25000\) 并进行一个循环展开。连续性非常好然后就过了。嘟嘟嘟。

[MXBZ2026 R3] 真皮 / CF819D Mister B and Astronomers

首先显然考虑对 \(a\) 做一个前缀和,记 \(\sum a=A\),那对于一个 \(t_0\) 形如要找到首个 \(a_i+kA\equiv t_0\pmod T\)。

经典地,你可以视作每个 \(a\) 每次在模 \(T\) 意义下步进 \(A\),那么这样会形成 \(\gcd(A,T)\) 个环环长均为 \(\frac{T}{\gcd(A,T)}\)。那么一个 \(a\) 的答案,只需考虑其所在环上下一个人的位置,二者环上间距即是。先考虑求环上间距,形如 \(a_x+kA\equiv a_y\pmod T\) 的 \(k\) 的最小正整数解,写一个 exgcd 即可。

考虑给环上点排序,取环上初始位置 \(p_i=a_i\bmod \gcd(A,T)\),你把上文 \(a_x\) 代成 \(p_i\) 解出 \(k\) 然后按 \(k\) 升序排序即可。

特殊地,若存在 \(a_x\equiv a_y\pmod T\),显然只保留更小的点即可,更大点答案必然为 \(0\)。

[MXBZ2026 R3] 好排列计数 / CF2154F2 Bombing (Hard Version)

你考虑对一个序列找到首个 \(x\) 满足 \(p_x\ne x\),则其必须被划分为 \([1,p_x)\) 和 \([p_x,n]\) 两个部分。那么只有 \(p_i=i\) 的序列会被算重,其若合法必然会被算 \(n-1\) 次,减一下即可。

你将 \([1,p_x)\) 内的看作红点剩下的看作蓝点,那么每个已知位置实际上限制了之前必须有几个红点与这个点的颜色,那么只需要考虑相邻限制就容易算出答案,于是有一个 \(O(n^2)\) 的做法。

然后一个关键观察是,\(a_i>i\) 的必然为蓝点、\(a_i<i\) 的必然为红点。那你发现最终数列一定满足一个前缀和一个后缀 \(a_i=i\),中间一段 \(a_i\ne i\)。若给定的位置均满足 \(a_i=i\) 是平凡的,枚举 \(a_i\ne i\) 的一段即可。后文仅考虑存在 \(a_i\ne i\) 的情况。

忽略两侧 \(a_i=i\) 的极长段,还是考虑相邻限制,分讨二者颜色,记首个蓝点的值为 \(k\):

  • 若同色,贡献为 \({j-i-1\choose a_j-a_i-1}\)。注意到与 \(k\) 无关。
  • 若异色,贡献为 \({j-i-1\choose a_j+a_i-i-k-1}\)。注意到有值仅当 \(k\in[a_i+a_j-j,a_i+a_j-i-1]\),只有 \(j-i\) 个有效值,因此你直接枚举就是 \(O(n)\) 的。可以先把所有区间取交集再去算。

[MXBZ2026 R3] 神秘题

注意到操作奇数次序列完全相同,操作正偶数次序列也完全相同,因此只需要维护操作一次和两次后的序列即可。注意特判初始序列。

考虑序列分块。先求第二行,我们只需要求第一行这个数在前缀出现了多少次,给每个块开个桶即可,是平凡的。考虑第三行,要求前缀中多少个元素的前缀出现次数与当前值相同,实际上就是求前缀中有几个元素出现了不小于该值的出现次数次。考虑给每个块做一个值域分块,维护每个元素在前缀中的出现次数,那么一次修改操作你枚举所在块往后的所有块,给每块内的值域分块做单点修改即可。

P7563 [JOISC 2021] 最悪の記者 4 (Worst Reporter 4) (Day4)

你环上的点权必须全部相等,你改成的值必然是基环树上某个点原来的值。考虑树部分的代价,并无一定策略,需要 DP。

容易设计 \(f(i,j)\) 表示做到 \(i\) 根权为 \(j\) 的方案,考虑转移,接一个儿子直接取后缀 \(\min\) 加上去,然后若 \(j\ne h_i\) 就加上一个 \(c_i\) 的代价,这个不妨改成 \(j=h_i\) 就减去 \(c_i\) 的代价做成单点减。你考虑直接用线段树合并去维护这个东西,直接维护后缀 \(\min\) 则序列单增容易维护。

考虑单点减,减完相当于给前缀取 \(\max\),但合并的时候直接下传复杂度就假了,你考虑若没有儿子等价于给另一棵树区间加,再维护一个区间加 tag 即可。最后环上点不急着算 \(c\) 取前缀 \(\min\),你枚举最终等于的值取最小值,暂不修改 \(c\) 时序列仍单增可以直接合并,手动处理 \(c\) 的贡献即可。

CF1039D You Are Given a Tree

考虑对一个 \(k\) 求答案。考虑贪心,从下往上,如果能连出一条长为 \(k\) 的链就连,否则选出一条最长的向上链。

你发现有一个自然根号,对于 \(k\ge \sqrt n\),路径条数不会超过 \(\sqrt n\)。考虑一个与路径条数有关的算法,显然 \(k\) 关于路径条数是单调的,你考虑对每个答案二分最后一个不少于他的 \(k\),复杂度 \(O(n\sqrt n\log n)\)。均衡一下块长还能做到 \(O(n\sqrt{n\log n})\)。

09.12

[MXBZ2026 R4] 道路开放

用 set 之类维护连续段再用 set 之类维护各段贡献即可。

[MXBZ2026 R4] 区间划分

不懂套一个图的意义,跑一遍搜索把所有环跑出来,然后每个环相当于一个区间,要求你划分的每个区间只能包含至多一个给定区间。注意到大区间套小区间大区间必然取不到,把他的限制存下来直接扔掉,剩下的区间端点单调,容易对每个左端点处理出其一步能跳到的最远位置,倍增跳即可。

[MXBZ2026 R4] 整倍分组

容易考虑组合意义,相当于每组选一个元素进行贡献。我们先 \(O(n^2m)\) DP 出每个 \(k\) 选出 \(k\) 个贡献元素的总贡献,然后考虑把剩下 \(nm-k\) 个元素分入这 \(k\) 组,枚举每组的元素个数就是一个可重集排列,就是求:

\[[x^n]\left(\sum_{i=0}^{\infty}(im-1)!^{-1}x^i\right)^k \]

然后往 NTT 想就有福了,因为我既不会默写 MTT,MTT 常数太大还过不去。需要进行一个根号卷积,把 \([1,B]\) 内所有次数都卷出来,然后以 \(B\) 次方的多项式为单位元把 \(kB\) 次方的多项式也都卷出来,查询 \(O(n)\) 把 \(k/B\) 和 \(k\bmod b\) 两个多项式卷出第 \(n\) 项即可。

[MXBZ2026 R4] 路径除雪

你考虑同一端点延伸出去的不同方向的路径,将其合并不劣,故而一个点的贡献,就是他的各出边匹配后剩下的边数乘上他自己的点权。记 \(S_x\) 为 \(x\) 的出边路径之和,\(M_x\) 为 \(x\) 最大的出边路径数,则其贡献为:

\[w_x\max(S_x\bmod 2,2M_x-S_x) \]

我们记 \(p_x=S_x\bmod 2,h_x=\lfloor S_x/2\rfloor\),则答案为 \(\sum_x w_xp_x+2\sum_xw_xh_x\)。不妨记 \(m_x\) 为边权取到 \(M_x\) 的 \(x\) 的出边,则 \(h_x=\max(0,2z_{m_x}-S_x-p_x)/2\)。

考虑一次修改 \((u,v,d)\) 操作影响,首先显然只会影响 \(u,v\) 路径上点。容易处理两端点,对剩下的点 \(x\),\(S_x\gets S_x+2d\) 则 \(p_x\) 不变,若 \(m_x\) 在路径上则 \(z_{m_x}\gets z_{m_x}+d\),\(h_x\) 不变,否则 \(h_x\gets\max(0,h_x-d)\)。

考虑快速维护修改,考虑树剖,拉出这一条路径,我们对其中 \(O(\log n)\) 个重链端点与其父亲也特殊处理,对于剩下完全在内部的点 \(x\),\(m_x\) 不在路径上仅当 \(m_x\) 在轻边上,你考虑将这类点挂到线段树上,用 SegmentBeats 去维护 \(h_x\) 区间加和区间取 \(\max\) 即可。考虑修改后 \(m_x\) 改变的情况,记 \(x\) 的父边与重儿子边的较大值为 \(b_x\),再维护一个 \(M_x-b_x\),每次执行区间减 \(d\),若有值为负则暴力搜下去更新其信息即可。

09.14

P10013 [集训队互测 2023] Tree Topological Order Counting

首先对每棵子树求出内部拓扑序方案数,那么对一个点,首先把排除他的子树的序列做出来,然后考虑把他的子树插入进去,你发现限制只有他的父亲在序列上的位置,做一个前缀和然后枚举他插入的位置即可。按 DFS 序做,容易撤销子树在父亲的影响。

CF2122G Tree Parking

考虑描述合法,关心点 \(i\) 的所有祖先,则他们必须完全被包含于 \(l_i,r_i\) 划分出的三个区间中。考虑从下到上构造,则父亲的区间不得与子孙的任一端点有交,共有 \(2sz_x-1\) 种插法。因而有转移:

\[f(x)=(2sz_x-1)(2sz_x-2)!\prod_{y\in\mathrm{Son}_x}f(y)(2sz_y)!^{-1} \]

展开一下得到 \(f(1)=\prod_{x}(2sz_x-1)!\prod_{x\ne 1}(2sz_x)!^{-1}=(2n)!2^{-n}\prod_xsz_x^{-1}\),因而我们只需求 \(\sum_T \prod_x sz_x^{-1}\) 即可。而一棵树的拓扑序个数为 \(n!\prod_xsz_x^{-1}\),因而我们可以转而求拓扑序个数。

考虑对一个拓扑序求树的个数,只需依次加入点即可,考虑叶子的限制,容易有一个 \(f(i,j)\) 表示考虑前 \(i\) 个点有 \(j\) 个叶子的方案数,有转移:

\[f(i,j)=jf(i-1,j)+(i-j)f(i-1,j-1) \]

这个东西是有组合意义的,\(f(n,k)\) 相当于长为 \(n-1\) 且有 \(k-1\) 对相邻上升的排列个数,之所以是 \(n-1\) 是因为你钦定了 \(1\) 为根,即欧拉数 \(A(n-1,k-1)\),最后再乘上 \((n-1)!\) 即拓扑序个数即可。

考虑求 \(A(n,k)\),尝试二项式反演,设 \(h(k)\) 表示钦定 \(k\) 个上升的方案,则相当于一个 \(n-k\) 段非空段的可重集排列,考虑生成函数:

\[\begin{aligned} h(k)&=n![x^n](e^x-1)^{n-k}\\ &=n![x^n]\sum_{i}{n-k\choose i}(-1)^{n-k-i}e^{ix}\\ &=n!\sum_{i=1}^{n-k}{n-k\choose i}(-1)^{n-k-i}[x^n]e^{ix}\\ &=\sum_{i=1}^{n-k}{n-k\choose i}(-1)^{n-k-i}i^n \end{aligned} \]

于是我们反演:

\[\begin{aligned} &\sum_{i=k}^{n-1}(-1)^{i-k}{i\choose k}h(i)\\ =&\sum_{i=k}^{n-1}(-1)^{i-k}{i\choose k}\sum_{j=1}^{n-i}{n-i\choose j}(-1)^{n-i-j}j^n\\ =&\sum_{j=1}^{n-k}(-1)^{n-k-j}j^n{n+1\choose j+k+1}\\ \end{aligned} \]

带入原式即可:

\[(2n)!2^{-n}n^{-1}\sum_{i=1}^{n-k}i^{n-1}(-1)^{n-k-i}{n\choose i+k} \]

CF2161F SubMST

考虑求一个集合的价值。考虑 Kruskal,按距离升序去枚举点对,则必然不会出现一条路径跨越另一点的情况,只需考虑各个点分割成的若干连通块,考虑一个块,则必然存在一个“根”满足深度最小同时到其他块内点的路径不经过别的块内点。除了根以外,你注意到其他点必然会向深度不比自己大的点连一条边,连多了可以调整更优,因而只需关心深度比自己小的点与自己的最近距离即可。

这个东西和块是无关的,因而可以直接做。将所有点按深度升序排序,同深度顺序不影响,对于每个点 \(i\) 按距离升序枚举自己前面的点,则之前枚举过的点必须不在点集里,还没枚举到的点以及更深的点随意,那么容易算出这条路径的贡献点集数。

P10064 [SNOI2024] 公交线路

首先可以只考虑叶子,你发现本质上要求存在点被所有路径经过。这样的点显然是一个连通块,你考虑点边容斥,用钦定某点被全部经过的方案数减去钦定某边被全部经过的方案数,这样每个连通块都只会被算一次。

考虑求钦定某点 \(x\) 被全部经过的方案,考虑容斥,以 \(i\) 为根 \(f(i,j)\) 表示子树 \(i\) 钦定了 \(j\) 个叶子不与 \(i\) 相连的方案数,转移只需枚举邻点,这样单点复杂度 \(O(n^2)\) 总复杂度 \(O(n^3)\)。考虑优化,你考虑最后一棵子树可以直接钦定其中所有叶子,不用容斥,那你钦定这棵子树为原树上的父亲块,这样只需容斥子树内部分,复杂度树上背包 \(O(n^2)\)。钦定边本质相同。

#18338. Discount Event

考虑一次修改后新的直径只有两种,要么是不经过修改路径的,要么是由修改路径的两条出边得到的。考虑后者,只需维护修改路径上最长与次长的出边,容易写一个树剖实现,特别地对于 LCA 需要维护其向上的最长出边,容易预处理。前者是类似的,对于 LCA 换根预处理其上方块的直径即可。

CF1658F Juju and Binary String

性质是答案不超过 \(2\)。你考虑破环成链扫,那么每次 \(1\) 的数量的变化在 \(\{-1,0,1\}\),则只要同时存在区间 \(1\) 数量不小于和不大于所求即可。注意到所有 \(n\) 个区间 \(1\) 的数量之和相当于每个数被算了 \(m\) 次,恰等于所需的 \(n\) 倍,故而必然存在。

09.15

[MXBZ2026 R5] 共振

考虑关心 \(a\) 的 \(\Delta\),则 \(\Delta_i\) 在总和的贡献系数为 \(2^{k-i}\),注意到 \(\sum_{i}\frac{n}{2^i}=O(n)\),因而各个 \(\Delta\) 可能的值总量是 \(O(n)\) 的,容易设计 DP \(f(i,j)\) 表示考虑到 \(i\) 剩余 \(2^{k-i}j\)(暂不考虑更低位)的方案,转移只需要一个后缀和即可。

[MXBZ2026 R5] 平衡

转化为折线图,那就是要求任意时刻非负,且最后一个数为全局最大值。

先贪心地处理非负,从前往后扫维护前缀和,如果为负了当前元素就必须删掉。显然删掉的总个数为 \(\min(0,-\min_i pre_i)\)。再考虑后者限制,记当前最大前缀和为 \(mx\) 全局和为 \(sum\),随便选 \(mx-sum\) 个 \(-1\) 删掉即可。

将二者求和,则前者可以和后者的 \(sum\) 合并掉变成初始全局和,考虑关心 \(mx\),有 \(mx=\max_ipre_i-\min(0,-\min_{j<i} pre_j)\),你发现这个东西就是最大子段和,直接上线段树维护一下做完了。

[MXBZ2026 R5] 树

考虑独立处理各质因子,则一条合法路径要求所有质因子路径出现次数最小值均为 \(0\)。你把每个质因子最长的出现次数最小值非零的长度求出来,最后答案就是所有因子答案最大值加一,如果不存在这样长的路径就无解。

对一个质因子 \(p\),你只保留为 \(p\) 倍数的边,然后对每个非单点连通块跑换根,求出每个点到子树内最大深度,与向上链最大深度,查询不同块答案为零,否则就可以用这两个信息求出来。判无解用的路径长度可以保留所有边同理求出。

考虑一次查询,设 \(u\) 深度更大,则 \(u\) 的父边必然被经过,只需枚举其质因子即可,可能需要一个跳祖先的过程,你对每个质因子的连通块都从原树最浅的开始搜就可以继承原树的形态,复杂度大体 \(O(n\log V)\)。

[MXBZ2026 R5] 重建

设 \(f(d)\) 表示原问题答案,考虑莫反,转而求 \(g(d)=\sum_{d|x}f(x)\),也就是要求最终 \(\gcd\) 为 \(d\) 的倍数。

考虑容斥,对各个 \(k\) 求出恰有 \(k\) 个元素不变的方案,那么这 \(k\) 个元素必须为 \(d\) 的倍数,容易预处理 \(cnt_d=\sum[d\mid a_i]\),则方案为 \({cnt_d\choose k}\lfloor\frac{m}{d}-1\rfloor^{cnt_d-k}\lfloor\frac{m}{d}\rfloor^{n-cnt_d}\)。反演回去即可。

[hidden] 期望

首先我们知道异或操作是有交换律的,因此插入位置实际上没有任何用处。

其次我们考虑逐位处理,考虑这样一个问题:一个零一序列,维护一个初值为 \(0\) 的变量 \(v\),每到一个位置有 \(\frac{1}{2}\) 的概率异或上它的值,求最后该值的期望值。

我们注意到,序列上所有 \(0\) 都没有任何用途。我们再注意到,只要原序列中存在 \(1\),那么每次都有 \(\frac{1}{2}\) 的概率使得当前值变化,因此最终值为 \(0\) 和为 \(1\) 的概率是相等的。

因此一位的期望值,实际上只与这一位是否存在 \(1\) 有关。于是我们可以简单维护每一位 \(1\) 的数量,每次添加撤销的时候 \(O(\log V)\) 枚举所有位更新信息即可。于是就做完了。

09.16

[MXBZ2026 R6] 拆页

容易考虑一个 \(O(n^4)\) 的 \(f(l1,r1,l2,r2)\),你分析一下有效状态只有大概 \({n\choose 4}\) 左右,滚一维空间就能过了。

[MXBZ2026 R6] 区间图

对于题中给定的限制,点双和边双都是不方便直接维护的,不过你可以简单地维护极大团,扫描线维护覆盖了当前点的区间,当抵达一个区间的右端时,当前区间集合就是一个极大团。

边双肯定考虑找桥,首先连通块数是容易维护的,其次你发现桥其实就是大小为 \(2\) 的极大团,存一下个数就做完了。

考虑点双,显然一个点双是一段连续的极大团,那么当两个相邻极大团交集为 \(1\) 时删去交集二者断开,两者属于两个不同点双,那就只需存一下这样的团对个数即可。考虑求两个相邻极大团的交集,我们在一个团结束时求其与下一个团的交集大小,实际上就是当前集合内右端点不为当前点的区间数量。

[MXBZ2026 R6] 树和 / P14515 [NFLSPC #8] P15732 [JAG 2024 Summer Camp #2] Do Make Segment Tree

容易有一个 \(f(i,j)\) 表示子树 \(i\) 价值和为 \(j\) 的最小代价,显然可以表示为若干个绝对值函数之和,于是是下凸的,因而转移的 \((\min,+)\) 卷积可以闵可夫斯基和做。注意到从下到上只会叠加 \(O(n)\) 个绝对值函数,因此差分值的绝对值是不超过 \(n\) 的,只有 \(O(n)\) 种差分值,直接维护区间即可,这样每次暴力跳祖先重构即可,复杂度 \(O(2^nn+qn^2)\)。

[MXBZ2026 R6] 带状图 / P14515 [NFLSPC #8] 小 P,小 W,棒棒糖

相当于每个点选一个存在的邻边,如果都不选就产生 \(j\) 的贡献。容易有一个 \(f(S)\) 表示 \(S\) 中的点集已经选过了,然后逐条边加入,容易做到 \(O(2^nm)\)。

考虑优化,显然逐层处理,同层直接做上述 DP 即可 \(O(2^km)\),考虑处理层间连边,每个点只往下连不超过两条,逐点去处理即可,直接做需要状压两层的状态,爆掉了。

但是不维护两层的状态是不可能的,尝试只维护有效的状态,上一层处理过的点无需维护,下一层尚未开始处理的或所有向上出边都处理完了的也无需维护。巧妙地,若 \(x\) 连向的两个点为 \(y,z\),则在一个新图上连边 \((y,z)\),若只有一条出边 \(y\) 就连边 \((y,y)\),那么你按边数减点数降序处理新图上的连通块,对每块跑出一个 DFS 树然后按 DFS 序处理树上边对应点,再处理块内非树边对应点,这样总状态数不超过 \(k+1\)。

09.17

#5438. Half Mixed

子矩形总数是 \(\frac{n(n+1)m(m+1)}{4}\),如果是奇数就无解。先考虑更简单的问题,尝试简化为一行同色,则只需第一列满足条件。要求 \(\frac{n(n+1)}{2}\) 为偶数。\(n(n+1)\) 需要是 \(4\) 的倍数,\(n,m\) 总有一个满足。

则要求 \(\sum\frac{i(i+1)}{2}=\frac{n(n+1)}{4}\land \sum i=n\)。

我们记剩余目标区间数为 \(s\),剩余长度为 \(r\),\(T_i=\frac{i(i+1)}{2}\),你考虑每次选的 \(i\) 只需满足 \(T_i+(r-i)\le s\land i\le r\) 即可,前一条件可以写作 \(T_{i-1}\le s-r\),相当于给 \(s-r\) 做关于 \(T\) 的分拆,而 \(T_1=1\) 故必然可行;考虑后一条件,你需要保证你的分拆时刻满足 \(i\le r\),你考虑每次选不超过 \(r\) 的最大合法 \(i\),\(T\) 大致是平方级别故块长减小很快,感性理解必然可以分解完。

#8056. Travel 2

考虑 DFS 树,但直接建树非树边很不好处理。我们对每个点当前弧优化把他所有边都搜一下,这里理论耗费 \(2m\) 次,若走进一个所有邻边都搜完的点,此刻他的所有邻边必然两侧都走过了,把他标记一下,然后枚举他的邻边,若对方尚未被标记就搜进去,搜完对方必然被标记且回到原地,再回溯回来,就相当于一条树上边,这样就是额外的 \(2n\) 步。

#8079. Range Periodicity Query

注意到,一个 \(p\) 若不是 \(S_i\) 的周期,则其必然不会是 \(S_{j>i}\) 的周期。故而可以对每个 \(p\) 维护出 \(t_p\) 表示最后一个以他为周期的时刻,查询就是求区间内 \(t_p\ge k\) 的最小 \(p\),我们去扫描 \(t\),然后就是一个区间 \(\min\)。

考虑求出 \(t_p\),二分答案,把最终字符串做出来然后每个时刻相当于一个子串,可以直接字符串哈希判,串长减循环长应为 border 长度,看是否为 border 即可。

#8074. Multiply Then Plus

直接线段树分治套李超是 \(O(n\log^3n)\) 的,不太牛。

考虑线段树维护凸包,建树可以枚举节点内所有直线做到 \(O(n\log n)\),查询不需要合并,对所有区间答案取最大值即可,把询问离线下来升序排序则查询总复杂度也是 \(O(n\log n)\) 的。

但这个东西也不支持修改,且插入元素是 \(O(\log^2n)\) 的。还是考虑线段树分治,你在线段树上每个节点跑一遍上述过程,只维护加在当前节点的线段以及当前节点包含叶子上挂的询问,每次只用做建树和查询,总复杂度 \(O(n\log^2n)\)。

P3780 [SDOI2017] 苹果树

虑去枚举最大深度,那么要选的苹果数量一定,能选的苹果也一定。按 DFS 序 DP,容易写一个 \(f(i,j)\) 表示考虑到 \(i\) 选了 \(j\) 个苹果的最大价值,不妨先存下走 \(i\) 之前的情况,在 \(i\) 的子树走完之后与其取 \(\max\) 以处理不走 \(i\) 的方案。

没有什么优化前途,我们重新审视 \(t=h+k\)。惊人地,这个东西可以视作你免费地选一条链,然后再去选 \(k\) 个点,如果链不是最深的显然不优不影响答案。这条链显然会下达某个叶子。将原树分作三部分:非链上点、链上免费点、链上付费点。先正序倒序各枚举一遍所有儿子以计算非链上点贡献,搜下来时默认当前点为链上点,先免费算上一个,回溯时再把这一个的代价加上即可。转移单调队列优化多重背包,复杂度 \(O(nk)\)。

P6326 Shopping

假如钦定买根的话就是树上依赖性背包,按后序遍历顺序处理并使用单调队列优化容易做到 \(O(nm)\)。那你去枚举一个根就能做到 \(O(n^2m)\),不太好过。

考虑优化,你发现后面枚举根的时候无需经过之前已经枚举过的根,那就可以上点分治,复杂度 \(O(nm\log n)\)。

09.18

AGC056B Range Argmax

直接对 \(x\) 计数判定需要单调栈不太有前途,尝试将 \(x\) 唯一映射到排列 \(p\) 上。我们降序填数,每次钦定填入所有可行位置中最小的位置。那么填到 \(u\) 上后所有经过 \(u\) 的都已确定,就划分成了 \([l,u),(u,r]\) 两个子问题,可以区间 DP。

考虑如何钦定当前填入位置是最小的,只需保证 \([l,u)\) 中下一个填入的最大值位置在至少一个以 \(u\) 为 \(x\) 的区间内即可。于是可以设计 \(f(l,r,p)\) 表示处理区间 \([l,r]\),填入的最大值应当在 \([p,r]\) 内的方案数,转移可以从 \(f(l,r,p+1)\) 继承然后就只需要处理最大值填在 \(p\) 的方案。

那么我们需要对 \((l,r,u)\) 预处理出在 \((l,r)\) 内且经过了 \(u\) 的区间的最小左端点,我们对每个 \(u\) 跑一个子区间信息和即可。

AGC067B Modifications

如何去描述一个合法的 \(a\)。考虑倒序撤销操作,每次选定一段颜色一致的段,将之撤销作通配符,所有段都能选上就合法,显然能撤就撤是不劣的。这个还是很不好做,选段要求整段颜色一致,整体性很强。

由于每个点都有区间覆盖,所需实际上就是要把所有点都变为通配符,对点考虑,只要有一个覆盖它的同色区间进行了合法操作它就变为通配符了,正难则反考虑容斥,钦定一些位置没有变为通配符,那么经过它的所有区间都是不能操作的。

不过需要保证钦定的这些点确实无法操作,要求不存在操作区间使得其中所有钦定点同色,我们关心之前最右边的钦定点,以及他之前首个与其不同色的钦定点位置即可。设计 \(f(l,r)\) 表示 \([l,r]\) 删空的方案数、\(g(l,r,p)\) 表示考虑区间 \(l,r\),\(r\) 为钦定点且最近的与其不同色的钦定点位置在 \(p\) 的方案数,预处理出各个三元组 \((l,r,p)\) 在只考虑 \([l,r]\) 包含的操作区间情况下覆盖了 \(p\) 的最大左端点即可。

09.21

CF1830D Mex Tree

将最终形态描述为若干 \(1\) 划分出 \(0\) 连通块。各连通块内部路径为 \(1\),大小为 \(c\) 贡献为 \(c(c+1)/2\),而跨连通块的路径价值为 \(2\),记 \(0\) 的总数为 \(C\),价值为 \(C(C+1)-\sum c(c+1)\),因而一种方案的总贡献即为 \(C(C+1)-\sum c(c+1)/2\)。

很难有优化前途,尝试往上下界方面想。答案显然是很大的,我们将其转写为 \(n(n+1)-\sum c_0(c_0+1)/2-\sum c_1(c_1+1)\),然后关心 \(\sum c_0(c_0+1)/2+\sum c_1(c_1+1)\) 的最小值。注意到黑白交替染色时,其值大致为 \(\frac{3}{2}n\),因而可知联通块大小均是 \(O(\sqrt n)\) 级别的,可以直接设计 \(f(i,j,k)\) 表示考虑到 \(i\) 连通块大小为 \(j\) 颜色为 \(k\) 的最小代价,空间复杂度动态回收一下是 \(O(n)\) 的,时间复杂度树上背包分析得是 \(O(n\sqrt n)\) 的。

#7905. Ticket to Ride

首先段的价值可以扫描线线段树维护,但我们希望做到 \(O(1)\) 查询,容易换成分块。考虑优化 DP 过程,式子是 \(f(r,k)=\max_{l\le r}f(l-1,k-r+l)+val(l,r)\),显然 \(val\) 满足四边形不等式,但是直接二分队列的话,你要对每个 \(k\) 维护队列,同时复杂度带 \(\log\) 不太好过。

你考虑直接维护每个 \(l\) 的价值,\(val(l,r)-val(l,r-1)=\sum _{r_i=r}v_i[l\le l_i]\),每次相当于一个前缀加,然后查全局 \(\max\) 即可,这样时间复杂度仍是 \(O(n^2\log n)\) 的且空间也没有优化。

但你考虑前缀加,维护差分值后相当于修改一个单点,同时前面的元素在某一时刻更大后会一直比后面的元素大,因而可以直接把后面比前面小的临段合并,每段维护区间最大值,全局最大值就是最后一段的值,用并查集实现复杂度 \(O(n^2\alpha(n))\)。

考虑空间的问题,上面的维护方式前后两项内二元差值分别为 \(r-k\) 和 \(r-k-1\),差一点就相等了。我们再维护一个 \(g(r,k)=\max \{g(r-1,k),f(r-1,k)\}\),转移 \(g\to f\) 则二元差值恒为 \(r-k\),只需按 \(r-k\) 升序枚举做即可完成。

CF1750G Doping

字典序更小不好做,暴力地枚举 LCP,再枚举下一位的值,然后只需要考虑剩下的部分,容易容斥,你发现下一位的值对后续过程影响只有常数种,故而可以预处理掉。式子是卷积形式,把生成函数写出来,发现一项是 \((1+x)^a\) 于是乘法可以秦九韶,就嘟嘟嘟了。

#5308. RPG Pro League

考虑判定能否凑出 \(x\) 对,显然可以跑二分图最大匹配,右侧点只有四种,\(DSB\) 以及 \(D+S\) 通配,左侧点只有 \(7\) 种,考虑霍尔定理,可以 \(O(2^4\times 7)\) 求得,容易二分答案求得。

考虑最小化代价,我们考虑按价值降序尝试删点,若剩下的点集无法组成最大匹配就必须保留,否则贪心地直接删即可,该贪心的正确性存在证明,但我不会。

考虑动态维护,也可以证明修改后其实只会进行一次与当前元素有关的替换。如果当前元素在集合内,尝试用集合外的元素进行替换,反之尝试替换集合内的元素,看是否仍有最大匹配,元素只有 \(7\) 种,维护每种的最值即可。

09.22

[MXBZ2026 R7] 自胡蹿

因为特殊的插入方式,能变成回文串,仅当原来的颜色序列是回文串。进行连续段缩点,然后枚举上面的串。显然在花费最小代价变成回文串后一直在中间加就可以,变成回文串就是把两边各部分段长标齐,先枚举回文串中点再枚举长度即可做到 \(O(n^2)\)。

[MXBZ2026 R7] 跳跃 / CF704B Ant Man 加强版

考虑对路径 DP,顺次扫描,假如是一个环的话,任意时刻经过当前段往左走的路径数等于往右走的路径数,算上起点终点二者至多差一,所以容易有一个 \(f(i,j,0/1/2)\) 表示考虑到 \(i\) 有 \(j\) 对路径两者相差情况,每个点就四种状态,复杂度 \(O(n^2)\)。

你考虑从小到大往路径中加入元素,先忽略 \(s,e\),推一下式子,假设 \(x\) 插入 \(y\to z\) 中,若 \(y>z\) 则只会将 \(y\) 往左走的贡献变为 \(y\) 往右走的贡献,否则将 \(z\) 从左来的贡献变为 \(z\) 从右来的贡献,然后必然加上 \(x\) 向左边的两个贡献。所以可以直接拿一个堆去维护所有可以插入的位置每次贪心取最小代价。

考虑 \(s,e\),在其之后的显然不受影响,在其之前的应特殊处理 \(s\to x,x\to e\) 的插入情况,容易实现。扫到 \(s,e\) 的时候往堆里加一个改变方向的选项。第一个点先强制加入避免各种特判。于是做到 \(O(n\log n)\)。

[MXBZ2026 R7] 套娃 / #9865. Dolls

显然区间越长越不牛,因此你考虑对每个左端点找到最长的右端点使得他们可以合并到一起,然后暴力跳就是,显然答案为 \(n\) 减最小段数。

一个区间 \([l,r]\) 能被合并,形如存在一个分界点 \(k\),满足 \([l,k],(k,r]\) 都是好的,且一侧的元素全都大于另一侧。更进一步地,你发现若一个区间 \([l,r]\) 是好的,则他的所有子区间都必须是好的,因为两个区间分别延伸之后不可能从不可合并变得可以合并。

那么,只需判定 \([l,r]\) 内每个子区间均存在一个 \(k\) 满足一侧元素全都大于另一侧即可。你考虑去枚举 \(v\) 然后转为 \(01\) 序列,那么符合条件的就是跨相邻两个连续段的区间,就可以得到若干合法矩形,那么可以对每个右端点维护出其最近的非法左端点 \(lb\),判定 \([l,r]\) 能合并的充要条件即为 \(\max_{i\in[l,r]}lb_i<l\)。

直接做矩形个数是 \(O(n^2)\) 的,但你注意到升序枚举 \(v\) 每次只会把一些 \(1\) 变成 \(0\),只用处理其相邻的两段,故而矩形个数可以降到 \(O(n)\)。容易扫描线求 \(lb\)。

[MXBZ2026 R7] 导览图 / #9805. Guide Map

假如所需 DFS 树一定,那么必然没有横叉边,只能有返祖边。假如存在 \(x\to y\) 的返祖边,记 \(c\) 为 \(y\) 的儿子满足 \(x\) 在 \(c\) 子树中,则需 \(c< x\)。

分开处理两棵树,\(1\) 所在树形态一定容易一次搜索得到答案,两树之间的边,由于第二棵树内点集一定,故只在于插入在第一棵树哪个点上,可以在搜索过程中顺便维护可行边数量。那么只需对第二棵树所有根的情况求和,考虑换根,需要求形如“子树内比某数大的元素个数”,离线扫描线即可。

09.23

[MXBZ2026 R8] 游戏

考虑一条链,你发现链头为 \(1\) 先手必胜,因为后手操作别的点必然把链头变为 \(1\),进而发现否则先手必败,于是只需要看根有几条邻边为 \(1\) 即可。

另一个思路是最终失败的时候,根相邻 \(1\) 的个数为 \(0\) 为偶数,而任意修改都会改变该值奇偶性,因而直接看奇偶性即可得知胜者。

[MXBZ2026 R8] 小伙伴

考虑讨论两个区间的关系,你发现相离或包含代价均为 \(len_1+len_2\),而相交时代价为 \(len_1+len_2-1\),假如在链上,那么代价就是长度和减去相交对数,连续相交的顺序处理即可达到此下界。

考虑在环上,一个性质是相交的任意看法都相交。因此只需要统计掉相交对数后,对每个点选择两个方向取距离较小值即可。

[MXBZ2026 R8] 奇怪的树

考虑统计答案,对各个 \(y\) 枚举 LCA 有点复杂,考虑对各个 LCA 统计 \(y\) 的个数,这个是平凡的,维护子树内特殊点编号和 \(S(x)\),则从 \(u\) 往根给各个 \(fa_x\) 贡献 \(S(fa_x)-S(x)\)。

考虑树剖,一棵树维护 \(S\),另一棵树维护答案,在答案树上对每个点维护 \(S(x)-S(son_x)\),\(son_x\) 为重儿子,那么统计答案时,单点修改 \(\log\) 个轻链的答案,剩下的重链连续段推 tag 维护历史信息和即可,注意到修改时只会对 \(\log\) 个轻链单点修改,因此历史信息和是容易维护的。

[MXBZ2026 R8] 三元组计数

考虑树。我们枚举 \(w\),求 \(u,v\) 的数量,直接用 \((n-1)^2\) 减去在同一棵子树内的选法即可。考虑一般图,我们边双缩点,同样枚举 \(w\),三点在不同边双的做法和树是类似的,三点在同一边双的另外两点可以任选,两点在同一边双的剩下一点同样可以任选边双外一点。

考虑动态维护,我们用并查集模拟缩点,考虑合并两个边双对答案的影响。后两者直接重算即可,考虑三点在不同边双的影响,维护每个连通块各子树大小乘积和,合并这个也是容易维护的。

P10208 [JOI 2024 Final] 礼物交换 / Gift Exchange

容易考虑转二分图,每个 \(A_i\) 向 \(B_{j\ne i}<A_i\) 的 \(B_j\) 连边,合法当且仅当存在完美匹配。

模一会可以发现,有完美匹配的充要条件为,每个 \([B_i,A_i]\) 区间都与另外的某一个 \([B_j,A_j]\) 区间有交。必要性显然,考虑充分性,考虑霍尔定理,显然只考虑把一个前缀的 \(A\) 选完不劣,那么左侧的 \(B\) 除了 \(B_i\) 显然都选上了,而 \(i\) 必然与某 \(j\) 有交,要么 \(A_j<A_i\) 则 \(A_j>B_i\) 把 \(B_i\) 选上,要么 \(A_j>A_i\) 则 \(B_j<A_i\) \(i\) 可以把 \(B_j\) 选了,故必有 \(|S|\le |N(S)|\)。

那么一次查询就是看只保留编号区间内的区间,是否存在孤立区间。对每个区间预处理出前后首个与之相交的区间 \(lb,rb\),处理这个平凡扫描线一下即可,判定的话我们扫描 \(R\),维护所有 \(rb>R\) 的区间,那么只需查这些区间编号在 \([L,R]\) 内的最小 \(lb\) 即可。

09.25

P7831 [CCO 2021] Travelling Merchant

只要能走到一个环就有解,因而容易先做一个拓扑把无解的都判掉。对于剩下的部分,容易考虑一个 \(f(x)=\min_e\max\{f(b_e)-p_e,r_e\}\),然而并没有一个很好的转移顺序。你考虑从边入手,每次处理剩余的 \(r\) 最大的边,更新 \(a_e\) 的 \(f\) 然后把这条边删掉,若 \(a_e\) 不余出度,则枚举 \(a_e\) 所有剩余的入边去更新另一端点并将其删除,重复执行直到所有剩余点均有出度,这样处理边的时候必然有 \(f(b_e)\le r_e\)。

P5521 [yLOI2019] 梅深不见冬

显然在一个点放上花后就把它所有儿子的花都拿回来。记 \(f(x)\) 为 \(x\) 点的答案,则相当于给 \(x\) 的儿子排序,最小化儿子序列的 \(\max_i\sum_{j< i}w_j+f(i)\)。临项交换,分讨一下得到按 \(w-f\) 排序即可。

AGC023F 01 on Tree

给儿子邻项交换,按 \(\frac{c_0}{c_1}\) 排序即可,每次找到这个最小的值合并给他的父亲即可,就是经典树上贪心形式。

09.26

P2414 [NOI2011] 阿狸的打字机

考虑 AC 自动机,如何完成一次查询,实际上就是求 trie 树上 \(y\) 到根的路径中有多少点在 fail 树上 \(x\) 点子树内,离线下来按 DFS 序做扫描线后者就是一个区间查询。

CF547E Mike and Friends

查询 \(k\) 在 \(S[l:r]\) 中出现次数。离线下来做拆分,考虑加入一个前缀的串后求答案,若 \(k\) 为 \(x\) 的子串次数形如 \(x\) trie 到根链上 \(k\) fail 子树内的点数。然后一个关键性质是你在 trie 上暴力跳父亲复杂度是 \(O(\sum |s|)\) 的。

P5840 [COCI 2014/2015 #5] Divljak

我们把 \(S\) 全部拉一起跑 ACAM,加入 \(P\) 时跑一遍匹配即可,考虑一次查询,直接求子树和的话会算重,考虑暴力去重,加入 \(P\) 的一个前缀时,找到他与之前的前缀最近的 LCA,然后在 LCA 处减一。将其所有前缀所在点离线下来按 dfn 排序则只需求相邻两项 LCA 即可。

CF1483F Exam

考虑去枚举 \(s_i\) 及 \(s_j\) 在 \(s_i\) 出现的右端点,则其必然是该位置最长的串,但这样还不能保证不存在 \(k\),一个思路是若存在 \(k\),则形如更右侧的右端点存在子串满足完全包含当前串倒序做维护最小左端点即可,但你考虑当前子串可能有一个很靠后的出现位置判不到,不过不存在 \(k\) 当且仅当 \(s_j\) 的所有出现位置均不符合上述条件,我们存下各子串的访问次数,容易得到其出现次数,则统计其答案仅当访问次数恰等于出现次数即可。

P5334 [JSOI2019] 节日庆典

Significant Suffixes 板子题。

任何一个循环排列必然形如原串的一个后缀拼接上其相应前缀。我们考虑暴力维护下可能成为答案的后缀位置,称之为关键后缀,然后在序列末尾加字符时动态维护该集合,则其有以下性质:

  • 任意时刻不为关键后缀的位置此后不会成为关键后缀。
  • 对任意两个关键后缀,较小者必然是较大者的一个前缀,否则二者已经可以比出优劣。
  • 相邻两个关键后缀,较大者长度必然大于较小者的二倍。考虑反证,此时相当于存在一个循环节出现了至少两次,不妨记两后缀为 \(AAB\) 和 \(AB\),则要么 \(B\) 更优,要么 \(AAB\) 更优,\(AB\) 必然不优。因此任意时刻关键后缀只有 \(O(\log n)\) 个。

那么就可以暴力维护。更新时,我们将新位置加入候选,然后从后往前依次按规则更新即可。关于判定是否为前缀的问题,任相邻两项均只需比较新多的一位即可。

查询时枚举所有候选,比较两个后缀 \(x<y\),记 \(k\gets x+r-y+1\),则只需比较 \(S[k:]+S[:x-1]\) 和 \(S[:y-1]\) 即可。考虑 Z 函数,若 \(z_k<y-x\),则已经可以比出优劣,否则比较 \(S[:x-1]\) 和 \(S[y-x+1:y-1]\),只需 \(z_{y-x+1}\) 即可。

CF710F String Set Queries

我们尝试维护 \(D\) 的 ACAM,你发现添加与删除都不容易。如果离线的话,可以考虑一个操作分块,维护块内最小集合的 ACAM,剩下 \(O(B)\) 个直接大力哈希即可。

但强制在线。首先删除可以做成插入 \(-1\),然后就只需要维护插入,继承分块思路写一个序列分块的话就是 \(O(|S|\sqrt m)\) 的,但可以直接二进制分组,然后就做到 \(O(|S|\log m)\)。

09.27

P12763 [POI 2018 R2] 诗集 Book of poetry

将元素加一对 \(s\) 取模,你考虑任意时刻只要有两种不同的值,则至少有一种是可以不增加空行的,同时若有一个元素会增加空行,填入另一个元素后再填他就不会了,这里要特判零。因此我们每次贪心地尽量填入众数,填不了看有没有次大值即可。

P5592 美德的讲坛

首先给 \(x\gets x-1\) 变成小于等于。你考虑在 trie 上做。考虑当前跑到了点 \(x\),第 \(k\) 层。如果之前没卡紧,当前子树就可以全选。否则,可以往一侧走,若 \(x\) 这一位为 \(1\) 还可以同时往两侧跑,后者贡献不好直接计算,我们扩展状态递归进去 \((u,v)\) 处理,二者为两子节点。

考虑处理 \((u,v)\),若之前没卡紧也可以全选,否则可以同时往同一侧走,若 \(x\) 这一位为 \(1\) 可以往相反方向走。这样子不可能再有更多元的状态,同时分岔状态有后继要求之前卡满,同时往一侧走和往相反方向走只有一者会继续往下走,总状态数实际上还是点数级别的,直接做就是 \(O(n\log V)\)。

考虑修改。你发现一次只会改 \(O(\log V)\) 个子树的复杂度,写一个 vis 然后每次跑记搜状物即可。

CF2211G Rational Bubble Sort

好神秘啊。你关心前缀和,则一次操作形如 \(s_i\gets \frac{s_{i-1}+s_{i+1}}{2}\),我们希望把折线变成下凸的。显然 \((0,0),(n,s_n)\) 二点恒定,我们关心这条直线,倘若存在直线下的点则必然可以不断操作其两侧的点使得符合条件,否则合法当且仅当不存在连续两个完全在直线以上的点。

09.28

CF436E Cardboard Box

考虑每次策略形如以下几种之一:新选一个 \(a\)、选一个 \(b-a\)、放弃之前的一个 \(a\) 选另一个 \(b\)、放弃之前的一个 \(b-a\) 选另一个 \(b\)。开若干个堆维护即可。

P10759 [BalticOI 2024] Jobs

考虑一个贪心策略,现在能走到的利润非负的点显然全都走完,但利润为负的点的价值有些复杂,以不同的初始价值进入会获得不同的收益,不过可以贪心地记录其收益非负的最小初始价值 \(f\),达到后就走进去不劣。

考虑求 \(f(u)\),维护当前余额 \(x\),初始令做 \(v_u\),开一个堆维护当前可达的 \(f(v)\),重复执行直到 \(x\ge f(u)\) 或所有 \(v\) 价值均为负,找一个最小的 \(f(v)\),若余额不够就提 \(f(u)\),然后走进去。求答案是类似的。

瓶颈在于求 \(f(u)\) 的过程,对每个 \(u\) 都要跑一遍,复杂度 \(O(n^2\log n)\)。考虑优化,首先每个 \(u\) 拓展到 \(f(u)\) 的过程是一定的,后续选 \(u\) 后可以直接跳过这些过程,维护该过程的利润以及剩下可以拓展的集合,某个祖先扫到的时候直接将拓展集合合并过去,同时你注意到该点本身在合并后就用不到了,故写一个可并堆即可,每个点的集合至多和他的一个祖先合并一次,故复杂度为 \(O(n\log n)\)。

P6943 [ICPC 2018 WF] Conquer The World

题意可以转化为,一些点需要点权,一些点可以提供点权,移动一个点权的代价为移动路径边权和。

容易考虑一个网络流,源点连提供点,需要点连汇点,加上所有树边,跑最小费用最大流。不是很牛,优化一下,路径和写作 \(d_u+d_v-2d_{\mathrm{lca}(u,v)}\),这样一组匹配就只与三个点的点权相关,容易关于点权重新建模。

考虑模拟费用流,\(T\to S\) 连边转化为最小费用可行流,但这样无法保证最大流的限制,我们给所有向汇点连的边权值减去 \(-\infty\) 最后再加回来即可。考虑消负环,我们从下到上枚举 LCA,维护各个子树内尚可用的 \(u,v\),每次取出最小的 \(u,v\) 若权值和为负就尽量配上即可,退流只需加入 \(2d_{\mathrm{lca}(u,v)}-d_{u/v}\),因为两条路径交错不优,所以不会存在 \(u,v\) 同时退流的情况,同时在一个点进行的匹配次数不超过度数次。

写一个可并堆即可做到 \(O(n\log n)\)。

P5211 [ZJOI2017] 字符串

容易考虑一个分块,对每块维护哈希与关键后缀,但这样查询你需要枚举每个块共 \(\sqrt n\log n\) 个后缀并进行 \(O(\log n)\) 的二分哈希比较,很不牛。

注意到合并两个区间的关键信息并不困难,保证左侧区间不长于右侧区间的情况下,可以直接继承右侧区间信息,再从左侧区间中选一个最优的即可,这样每个点维护的后缀数量在 \(O(\log n)\) 且必然包含了所有关键后缀。那我们用线段树维护区间关键后缀,用分块维护哈希,即可做到 \(O(q\log^3n+q\sqrt n)\)。

yukicoder No.1001 注文の多い順列

如果只有一种 \(t\) 是平凡的,升序排序顺次扫一遍即可。对于同时有两种 \(t\) 的情况,对于 \(t=1\) 的我们去做容斥,钦定其中一些不合法,这样不合法的限制也是填在 \(<x\) 的地方,就可以延续上述做法了。

gym106559B Buhăiești

不妨去枚举首个不同的位置,那么往后就只需考虑 mex 限制。

设计状态 \(f(i,j,k)\) 表示考虑到 \(i\),现在 mex 值为 \(j\),有 \(k\) 个空闲值要填到 \(>j\) 的位置上,也就是贡献延后。转移枚举当前元素填在哪里,三种情况,只有恰填到 \(j\) 上是特殊的,枚举新的 \(j\) 和填入的个数,填入方案就是一个斯特林数。但直接枚举复杂度达到了 \(O(n^6)\),考虑优化,你一步一步转移,升序枚举 \(j\) 然后转移给本位的 \(j+1\),这只需枚举几个数填在 \(j\) 上,复杂度 \(O(n^5)\)。

首个不同的位置比较特殊,因为你要保证它小于 \(b\),如果初始让他填在 \(>j\) 的位置,在后续需要特殊处理,再开一维表示这个数是否已经填入即可。

#10210. Misunderstood … Missing

倒着做,关心后缀攻击次数与各攻击时刻与当前的距离和,直接放进状态即可。

10.03

P9197 [JOI Open 2016] 摩天大楼 / Skyscraper

连续段 DP 板子。

P10547 [THUPC 2024 决赛] 排列游戏

首先并不是所有排列都可以被生成的。初始有 \(n\) 个置换环,每次操作改变置换环个数奇偶性,因此最终序列必然有偶数个置换环。

考虑怎样还原一个排列代价最小,显然答案下界是 \(\sum |p_i-i|/2\),然后怎么构造证一下可得必然可以抵达下界。

考虑计数。\(|p_i-i|\) 贡献形式很麻烦,实际上 \(\sum|p_i-i|\le 2m\iff \sum[i<p_i](p_i-i)\le m\),因而我们只需关心右向段段长。

考虑从左到右处理,每个点有几种情况:新开一条链、新开一个自环、接在前面一条未完成链的开头或结尾、连接前面两条链的首尾、把前面一条链首尾相接连成环。对此设计 \(f(i,j,k,l)\) 表示考虑到点 \(i\)、前面有 \(j\) 条链、当前贡献和为 \(k\)、置换环个数奇偶性为 \(l\)。其中可以证明 \(j\le \sqrt m\),因而可以做到 \(O(nm\sqrt m)\),多测转移一致离线下来跑一次即可。

P10197 [USACO24FEB] Minimum Sum of Maximums P

做过。\(\max\) 写成 \(\frac{a+b+|a-b|}{2}\) 然后关心 \(|a-b|\),发掘一下填入性质可以写一个区间 DP 然后定值状压即可。

#9220. Bus Analysis

做过。有一个 \(f(i,x)\) 表示考虑到第 \(i\) 点花费 \(x\) 能走到的最远距离(钦定超过 \(a_i\)),记 \(x_0\) 是最小的能超过 \(a_i\) 的花费,则只有 \(x_0,x_0+1,x_0+2\) 是有效的。因此 DP of DP 只需 \(F(i,x,f(x),f(x+1),f(x+2))\),显然爆了,但可以把 \(x\) 一维去掉,\(F(x)\to F(x+1)\) 的时候把 \(\delta\) 的贡献算入答案即可。

CF1111D Destroy the Colony

事实上只需要求出“选定一些字符满足和为 \(\frac{n}{2}\) 且 \(x,y\) 上的字符包含于其中”的方案数即可,询问种数显然只有 \(O(|\Sigma|^2)\) 种。显然考虑背包,把 \(x,y\) 回退掉即可。

P6009 [USACO20JAN] Non-Decreasing Subsequences P

矩阵或猫树,猫树空间有点炸需要离线下来做。

CF2004G Substring Compression

首先有一个显然的 DP 是 \(f(i)\) 表示前缀处理到 \(i\) 的最小长度,转移枚举之后两段,复杂度 \(O(n^3)\)。考虑优化,你发现次数串长度必然为 \(1\),否则不优,因此分割方案一定,上述 DP 可以做到 \(O(n^2)\)。

继续优化,你考虑把一段的贡献下发到单点,那么只关心该段的重复次数,因而可以设计 \(f(i,j)\) 表示考虑到 \(i\) 最后一串重复次数为 \(j\) 的最小长度,特殊地钦定 \(j=0\) 表示上一段已经结束防止最后一个次数串没有后续的情况。这样即可做到 \(O(nw)\),\(w=10\)。

现在有多次区间查询,容易把上述转移写成矩阵形式,直接上线段树即可做到 \(O(nw^3\log n)\),比较不牛,注意到查询长度均为 \(k\),我们每 \(k\) 个分一组每组跑出组内前后缀答案,查询只需合并两组的信息,复杂度 \(O(nw^3)\)。

10.04

[hidden] sequence

这个求和显然没有性质,放进状态。存在一个 \(f(i,j,0/1,0/1)\) 表示和为 \(i\) 最后一位 \(\bmod k=j\) 首位选没选此前最后一位选没选,转移要么不封顶,要么封顶然后首尾相连,同时维护方案数和价值和即可。

直接做是 \(O(nk\min(n,2^w))\) 的。有点不牛。考虑优化,如果不考虑封顶的话转移实际上只有 \(k\) 种,而封顶唯一影响就是与开头的贡献,转移后一并处理即可,转移过程可以忽略。一次枚举整个 \(A_i\) 有点不牛,我们考虑将其拆分到各二进制位上,则只需再开一维位数,复杂度 \(O(nkw)\)。

AT_utpc2023_p Priority Queue 3

考虑关心最大的尚未进入 \(Y\) 的关键元素及其当前状态,这样可以加入的非关键元素数量已知,更小的已加入关键元素不妨延后决策,记录下在 \(X\) 内的关键元素个数即可。容易设计 DP,只有在弹出最大关键元素时才去枚举下一个最值,因而容易做到 \(O(n^3)\)。

ARC231D Choose Your Role

题中给出的两种操作显然是对称的,考虑构造一组相似的堆与石子的对称,给所有石子按 \(1\sim n\) 编号,则初始时堆 \(i\) 有石子 \(j\) 充要于堆 \(j\) 有石子 \(i\),则先手任意拿取石子后,后手均可以拿掉对应堆的对应石子维护对称性,因而后手必胜。

ARC231E Odd Inversion

逆序奇偶性的一个常见 trick 是关心奇数方案减去偶数方案。对于本题,从前往后 DP,考虑加入 \(B_i\) 的贡献,分讨:

  • \(B_i>A_{i-1}\),则不会产生任何逆序。
  • \(B_i\le A_{i-1}\land B_i\ne B_{i-1}\),你发现这种情况下奇数方案与偶数方案个数是相等的,因为你可以 swap \(B_i,B_j\) 使逆序数恰变化 \(1\)。
  • \(B_i\le A_{i-1}\land B_i=B_{i-1}\),这时候 \(B_i\) 产生的逆序数等于 \(B_{i-1}\) 产生的逆序数,二者加起来必然是偶数,因而这种情况下逆序奇偶性只需关心前缀 \(i-2\) 的逆序数。

容易对此 DP,奇数加偶数的方案就是 \(\prod A_i\),于是就能求出奇数的方案。

10.05

QOJ17412 Sequence Domination

不妨关心 \(d_i=a_i-b_i\),则要求为 \(\sum d_iv_i\ge 0\),确定 \(d\) 后方案数为 \(\prod m-|d_i|\)。\(v\) 序列的限制很神秘,关心 \(u_i=v_i-\sum_{j>i}v_j\),则 \(u\in N\),把 \(\sum d_iv_i\) 拆给 \(u\),推一下式子,另定义 \(w\) 满足 \(w_1=0,w_{i+1}=2w_i+d_i\),则 \(u_i\) 的系数为 \(w_i+d_i\)。

则题目限制相当于,任意时刻均需满足 \(w_i+d_i\ge 0\)。显然有 \(|d_i|<m\),不妨记 \(k=m-1\),则任意时刻 \(w_i\ge k\) 时此后 \(d\) 取任意值均合法,可以合并这些状态。于是设计 \(f(i)\) 表示当前 \(w=i\) 的方案数,特别地 \(i=k\) 表示 \(w\ge k\)。

考虑转移 \(f(j)\to f'(i<k)\),则 \(d=i-2j\),因而有 \(f'(i)=\sum_{j=0}^i(m-|i-2j|)f(j)\)。分开处理 \(\frac{i}{2}\) 前后的 \(j\),容易前缀和 \(O(1)\) 求得。对于 \(f'(k)\),易知 \(f'(k)=m^2f(k)+\sum_{j=0}^{k-1}\sum_{d=k-2j}^k(m-|d|)f(j)\),同样容易前缀和处理内层循环,容易做到 \(O(m)\),故总复杂度 \(O(nm)\)。

P17597 「RiOI-8」桜羽 エマ

距离可以直接写成深度差,如果是一条链是平凡的可以直接 NTT。考虑树的情况,考虑长剖,对每个长链维护链头子树内各深度 \(a\) 和,然后对长链跑一次卷积即可。你发现这样会算多,一个点可能会统计非子树内的答案。进一步的,假设当前长链所有轻子树均已处理完毕,则链上一个深度的点算多的贡献,等于当前长链链头子树内与他所有同深度的轻部分点的答案之和,枚举轻子树部分深度减掉即可。

10.06

P17628 信封的选择

先考虑只有一条线段的情况,不难想到打一个翻转 tag 然后每次暴力让小的翻给大的,复杂度 \(O(n)\)。

考虑多条线段,显然一条一条处理,一个思路是维护颜色连续段,那么每次操作至多使得连续段数加一。考虑根号分治,若连续段数不超过 \(\sqrt n\) 就暴力模拟,否则当前线段已经被操作了至少 \(\sqrt n\) 次,这样的线段不超过 \(\sqrt n\) 个,我们直接跑上面的暴力即可,复杂度 \(O(n\sqrt n)\)。

P17629 永远的朋友

拼好题。先考虑与,显然从高位往低位贪心,一位能为一仅当所有元素这一位均为一,那你发现,关心 \(s\) 的 \(\mathrm{highbit}\),这一位为 \(0\) 的元素必然执行异或操作,反之必然不执行,因此要执行的元素集合是一定的。更进一步,对于 \(s\) 为 \(1\) 的其他位,这一位可以为 \(1\) 仅当这一位为 \(1\) 的元素集合与 \(\mathrm{highbit}(s)\) 位完全一致,写一个异或哈希即可。

再考虑或,每一位只要存在一个 \(1\) 就能为 \(1\),也就是说为 \(0\) 当且仅当操作的下标集合恰等于这一位为 \(1\) 的下标集合,你发现下标集合至多有 \(32\) 个,而操作方案有 \(2^{len}\) 种,故而只要区间长度超过 \(5\) 就必然存在一种选法使得 \(s\) 的各为 \(1\) 位或和均为 \(1\),否则我们对每个询问跑一个 \(2^{len}len\) 的暴力即可。

P11316 [RMI 2021] 去 M / NoM

考虑容斥,设计 \(f(i,j)\) 表示从小到大考虑到余数 \(i\),共填入 \(j\) 个非法对的方案数,有转移:

\[f(i+1,j+x)\gets f(i,j){n-j\choose x}\frac{\lceil\frac{2n-i}{m}\rceil!}{(\lceil\frac{2n-i}{m}\rceil-2x)!} \]

各个 \(i\) 的 \(x\) 的总枚举量是 \(O(n)\) 的,因而复杂度 \(O(nm)\)。

#4279. Saddle Point

考虑从小到大枚举值,则钦定一个鞍点相当于钦定一对此前未钦定过的行列并以其为极大值,对此容斥,设计 \(f(i,j)\) 表示考虑到值 \(i\) 钦定了 \(j\) 个鞍点并填好对应行列的方案数,有转移:

\[f(i+1,j+x)\gets f(i,j){n-j\choose x}{m-j\choose x}x!i^{(n-j)(m-j)-(n-j-x)(m-j-x)-x} \]

答案即为 \(\sum_{j\ge 1} f(k,j)(-1)^{j-1}k^{(n-j)(m-j)}\)。

P8329 [ZJOI2022] 树

考虑对每个点恰为一棵树上的叶子容斥,求一个容斥系数,异或求积显然没有前途,设其在两棵树上是否为叶子状态为 \(x,y\),则其系数可以表示为 \(x+y-2xy\),也就是钦定为一棵树上的叶子系数为 \(+1\) 而同时钦定为两棵树上的叶子系数为 \(-2\)。

因而考虑 \(ABC\) 三类点分别表示钦定为 \(T_1,T_2\) 的叶子及同时钦定为两侧的叶子,对此 DP,加入一个点时同时考虑其在两棵树上的父亲,你关心他前面非 \(T_1\) 叶子的点和后面非 \(T_2\) 叶子的点数,因而有一个 \(f(i,a,b)\) 表示顺序考虑到点 \(i\),此前有 \(a\) 个非 \(T_1\) 叶子点出现过,此后还有 \(b\) 个非 \(T_2\) 叶子点要出现。点 \(1\) 必然为根不为叶子,因而有初始化 \(f(1,1,b)=b\)。

考虑转移,分讨三类点,若加入一个 \(A\) 类点,有 \(f(i+1,a,b-1)\gets f(i,a,b)a(b-1)\),\(B\) 类点有 \(f(i+1,a+1,b)\gets f(i,a,b)ab\),\(C\) 类点有 \(f(i+1,a,b)\gets -2f(i,a,b)ab\)。最终 \(n\) 必然是根非叶子,因而答案即为 \(\sum f(n-1,a,1)\)。

10.07

删帧平滑

容易考虑设计 \(f(i,j)\) 表示最后两个选中元素是 \(j,i\) 的最优代价,转移把平方项拆开你发现是一个关于第三个项的一次函数式,一个简单的思路是对每个点开一个李超,刷表使得只用开一棵树,离散化一下 \(O(n^2\log n)\) 可以通过。

可以去掉 \(\log\)。还是顺序扫描中间点,按 \(a\) 给所有下标排序,然后就能单调插入和查询,维护凸包即可,排序可以放在外面排一遍,复杂度 \(O(n^2)\)。

短报码

容易在 AC 自动机上 DP \(O(2^mlmw)\) 求出任意集合共同的可行方案数。后文称选了同一个串的为一团,一个思路是容斥使得任意大小不小于二的极大团的系数均为 \(0\) 否则为 \(1\),可以 DP 跑出容斥系数,但我赛时没想到这么搞。另一个思路是对边容斥,存在连边当二者选了同一个串,合法情况就是不存在连边。还是考虑 DP,\(f(S,i)\) 表示考虑了 \(S\) 集合内的点,钦定了 \(i\) 条边的方案数,转移枚举 \(\mathrm{lowbit}(S)\) 所在的连通块,需要求出 \(g(n,i)\) 表示用 \(i\) 条边连通 \(n\) 个点的方案数,容易容斥得到。复杂度 \(O(2^mlmw+m^6+3^mm^2)\)。

短时校准

容易考虑背包,\(D\) 的限制可以直接双指针,但是这个背包无法撤销,很典地我们考虑对顶堆状物,左侧查询触碰中点就重构,以当前区间中点重建背包,复杂度均摊下来是 \(O(n2^b)\) 的,但空间有点炸,你考虑右侧查询必然单增,因此右侧只需要 \(O(2^b)\) 的空间,空间就减半了,可以通过。

双机分流

考虑计算一组的代价,首先显然按 \(w\) 降序处理,一个点的代价为 \(\lceil\frac{rk}{2}\rceil w\)。这个东西显然很难直接处理,按权值升序做连续段也很难维护。

考虑大力数据结构,我们开一棵权值线段树,\(\lceil rk/2\rceil\) 实际上等价于黑白染色后的 \(rk\),维护子树内黑白点数和价值和即可,单点修改 \(O(\log n)\) 查询 \(O(1)\)。这个贡献显然是有决策单调性的,直接上分治,复杂度 \(O(nk\log^2n)\)。

归档日志

尝试对一个编号序列计算合法时间差个数,顺次扫描维护当前覆盖线段条数即可统计在库时长和。我们将编号序列抽象为加入和删除,则可以设计 \(f(i,j,k)\) 表示考虑到 \(i\) 剩余 \(j\) 条线段在库时长和为 \(k\) 的方案数,所求即为 \(f(2n,0,k<B)\)。

但一个问题是有 \(d\) 的限制,考虑决策延后,你在抵达一个 \(d_i\) 的时候再把这些点对应位置给确定下来,利用上面的状态已然可以得知此前的添加次数和删除次数。然而还要枚举本段长,你按模 \(j\) 同余类做前缀和即可。最终复杂度 \(O(n^2B)\)。

联络站

考虑点边容斥,\((v_1-e_1)(v_2-e_2)=v_1v_2-e_1v_2-v_1e_2+e_1e_2\),因而要考虑四种钦定情况。在钦定一对点后,对每个部门求出同时覆盖这对点的方案数,然后跑一个背包即可。数据范围允许我们枚举点对后枚举部门,不过不能枚举路径,你预先枚举部门,做树上差分,类似一个二维矩形加,拆成向上链之后枚举两棵树上两条链的两对端点,其二维点差分系数就是两个点原差分之积,然后做一个类似二维前缀和的二维子树和即可。

10.08

#779. 命运歧途

考虑容斥,钦定一些相差为 \(k\) 的元素相邻,独立处理各同余类,容易设计 \(f(i,j,0/1)\) 表示链长为 \(i\) 共分了 \(j\) 段当前点是否要向后连边的带系数方案数,系数是长度超过 \(1\) 的带一个二的系数,然后把各同余类的信息卷起来,就得到了单次询问 \(O(n^2)\) 的做法。

考虑多次询问,记 \(F_i=\sum _jf(i,j,0)x^j\),若 \(n=qk+r\),则结果为 \(F_q^rF_{q+1}^{k-r}\),我们升序枚举 \(k\),每次保留共同因子,只撤销及加入变化因子,撤销用长除法,注意到结果多项式的最高次数为 \(x^n\),而 \(F_i\) 的最高次数为 \(x^i\),因此执行一次 \(F_i\) 的修改是 \(O(ni)\) 的。

总变化长度之和有一个自然根号,\(k\le \sqrt n\) 时每次替换因子长度和至多 \(O(n)\),而 \(k>\sqrt n\) 时有 \(q<k\),\(k\) 变化时 \(q\) 至多变化 \(1\),分讨变化与否两种情况:

  • 若 \(q\) 不变,有 \(r'=r-q\),故而我们只需更改 \(O(q)\) 个因子,长度是 \(O(q^2)=O(n^2/k^2)\),一次变化复杂度就是 \(O(n^3/k^2)\),有:

    \[\sum_{k=\sqrt n}^nk^{-2}<\int_{\sqrt n}^{\infty}x^{-2}dx=-x^{-1}\big |_{\sqrt n}^{\infty}=\sqrt n^{-1} \]

    因而总复杂度 \(O(n^2\sqrt n)\)。

  • 若 \(q\) 变化,有 \(r<q\),同时可推得 \(r'=r-q+k+1\iff q=k+1+r-r'\),同样可以推出变化长度和是 \(O(q^2)\) 的,然后就和上一种情况一致。

故而可以分析出复杂度 \(O(n^2\sqrt n)\)。

#10781. Permutation Pair

首先可以将矩阵变化为一个 \(n\) 的排列,每个排列对应了 \(n!\) 种矩阵。

那么就相当于要求公差为 \(\pm1\) 的极长连续段长度不超过内部元素 \(a\) 的最小值,逐列处理的话下标与值域限制是分离的,我们逐行处理,那么一个连续段合法当 \(r-l+1\le \min_{i=l}^r a_i\)。

考虑划分出合法连续段组,然后再求他们的合法排列数。求合法排列数需要得知总段数和长度为 \(1\) 的段数,两部分拆开复杂度过高,考虑一起做。设计 \(f(i,j)\) 表示前 \(i\) 个元素分了 \(j\) 段的带系数方案数,\(g(i,j)\) 表示最后一段还没结束且暂不统计最后一段的方案数,容易处理得到 \(l_i\) 表示最小合法左端点,考虑转移:

  • 首先新加一段进去,如果钦定和前面的接一起带一个 \(-1\) 的容斥系数:

    \[g(i,j)\gets \sum_{k=l_i}^{i}f(k-1,j)-g(k-1,j) \]

  • 然后处理当前段结束的情况,注意单点不带 \(2\) 的系数:

    \[f(i,j+1)\gets 2g(i,j)-f(i-1,j) \]

容易做到 \(O(n^2)\)。

P9745 「KDOI-06-S」树上异或

异或和是个很难处理的东西,我们考虑拆位,那么相当于每个块选择一位乘上其在这一位的异或权值。容易设计 \(f(i,j,0/1)\) 表示考虑到 \(i\),其当前所在连通块选了第 \(j\) 位且当前异或权值为 \(0/1\) 的子树内权值积和(不算所在块),转移枚举儿子合并即可,复杂度 \(O(n\log V)\)。

ARC124E Pass to Next

设第 \(i\) 个人传给后一个人的球数为 \(b_i\le a_i\),则 \(x_i=a_i-b_i+b_{i-1}\),注意到若所有 \(b\) 统一加减那得到的序列不变,因此不妨钦定 \(b_{\min}=0\)。

考虑贡献形式,不妨组合意义,每个元素从三项中选一项,选 \(b_{i-1}\) 一项的贡献不妨在 \(i-1\) 就处理掉开一维状态记录一下即可,破环成链注意首尾,那么转移形如一个 \(f'\gets f\sum_{b=0}^a b\),显然可以 \(O(1)\) 计算,再额外开一维记录是否存在 \(b=0\) 即可。

[?] 神秘树上期望题

题意: 给定一棵 \(n\) 点有根树。随后每次均匀随机选择一个已有点作为父亲,加入一个新点,共加入 \(m\) 个点。在最终树中均匀随机选择一个叶子,划去该叶子至根的路径。设最终树中点 \(u\) 的儿子数为 \(d_u\),求未划去点的 \(\max(d_u, 1)\) 乘积的期望,空乘积为 1。\(n, m \leq 400\),答案对 998244353 取模。

注意到有儿子被划去的点自己必然被划去,因此留存点的所有儿子均留存,因此一个局面的价值可以直接用所有点儿子数之积除以被划去点儿子数之积表示。

被划去点儿子数之积的倒数有一个很巧妙的组合意义,这等价于在树上每次等概率随机选一个儿子走进去直到走到一个叶子的概率,而一棵树上所有叶子此值之和恰为 \(1\),因而一棵树的价值恰为所有点的儿子数之积除以叶子个数。

考虑贡献形式,可以视作每个点选一个儿子。设计 \(f(i,j,k)\) 表示考虑到 \(i\) 个点,有 \(j\) 个叶子,\(k\) 个非叶子点尚未选择儿子的方案数,容易 \(O(n^3)\) 转移。

#5097. 小 P 爱学习

容易组合意义视作每组选一个元素求积。不妨先选出关键元然后再把剩下的元素按条件分组进去。选关键元可以直接 \(O(n^2m)\) 背包。

考虑实现把剩下的元素分组进去,一个大小为 \(ik\) 的组系数是 \(\frac{x^i}{(ik-1)!}\),相当于一个多项式的 \(n\) 次幂,根号求幂即可。复杂度 \(O(n^2\sqrt n)\)。哦前面模拟赛拉过。

#8180. Bridge Elimination

组合意义,对每个边双选一个点权。可以先考虑各边双内部的构造,最后再给他们连成一棵树,由 Cayley 公式知后者系数为 \(n^{m-2}\prod c_i\)。

考虑 \(n\) 个点如何连成一个边双,考虑容斥,设计 \(f(i)\) 表示 \(i\) 个点连成一个边双的方案数,转移枚举一个钦定点所在边双,然后你发现还要求一个 \(n\) 个点连通的方案数,类似地容斥即可。复杂度 \(O(n^2)\)。

不妨先 \(O(n^2)\) 背包跑出选出 \(k\) 个关键点的价值和,然后把剩下的点分配进去,一个分配了 \(x\) 个数的组的系数为 \(\frac{x+1}{x!}f(x+1)\),对每个 \(k\) 跑一个 \(O(n^2)\) 的背包即可,复杂度 \(O(n^3)\)。

P14686 [ICPC 2025 Yokohama R] Charity Raffle

考虑描述最终合法的奖品数量序列。首先所有元素之和应为 \(k\),其次每个元素都必须满足,要么前面有不小于他的元素,要么后面有不小于他减一的元素,你发现这是充要的。然后你发现只要第一个最大值满足后面有不小于他减一的元素就可以了。

对于任意一种情况,我们将最后一个最大值加一,必然可以唯一得到一个非法情况,同时所有非法情况均可如此生成,因此非法情况数恰等于总和为 \(k-1\) 且最大值不超过 \(m-1\) 的方案数,跑一个容斥即可。

#8184. Different Summands Counting

对序列统计很不好做,我们把贡献下发到权值上,对每个权值求出他贡献的序列数,容易有:

\[[m\mid n](-1)^{m-1}+\sum_{i=1}^{m-1}(-1)^{i-1}{m\choose i}\sum_{v=1}^{\lfloor(n-m+i)/i\rfloor}{n-iv-1\choose m-i-1} \]

显然考虑快速处理右边的求和式,相邻两项上指标差 \(i\),考虑范德蒙德卷积的差分形式,有:

\[{n+v\choose m}-{n\choose m}=\sum_{i=1}^m{v\choose i}{n\choose m-i}\implies v{n\choose m-1}={n+v\choose m}-{n\choose m}-\sum_{i=2}^m{v\choose i}{n\choose m-i} \]

记 \(t=\lfloor(n-m+i)/i\rfloor\),设计 \(F(r)=\sum_{v=1}^t{n-iv-1\choose r}\),则由上式可知:

\[\begin{aligned} F(r)&=\sum_{v=1}^t\frac{1}{i}\left({n-(v-1)i-1\choose r+1}-{n-vi-1\choose r+1}-\sum_{j=2}^{r+1}{i\choose j}{n-iv-1\choose r-j+1}\right)\\ &=\frac{1}{i}\left({n-1\choose r+1}-{n-ti-1\choose r+1}-\sum_{j=1}^r{i\choose j+1}F(r-j)\right) \end{aligned} \]

于是我们就可以递推得到所需的 \(F(m-i-1)\) 了,复杂度 \(O(m^3)\)。

10.09

[MXBZ2026 R10] 据点 / ABC318F Octopus

将 \(a\) 降序排序,那么就是要求每个 \(a_i\) 满足与 \(x\) 距离大于 \(a_i\) 的点个数不超过 \(i-1\) 个,我们枚举 \(a_i\) 再枚举 \(x\) 左侧首个与 \(x\) 距离大于 \(a_i\) 的点,容易得到合法的 \(x\) 的一个区间,那么 \(a_i\) 符合条件的 \(x\) 范围就是 \(O(n)\) 个区间的并,我们把所有 \(n\) 组区间求交即可,求交后最劣情况下新的区间数为原区间数之和级别,因而是 \(O(n^3)\) 的,但是显然跑得非常快。

[MXBZ2026 R10] 重抽 / P4745 [CERC2017] Gambling Guide

首先容易得到 \(f_x=a_x+\deg_x^{-1}\sum_y\min(f_x,f_y)\),这个 \(\min\) 显然很不好处理,我们放缩一下,加入钦定 \(S\) 中的 \(y\) 取 \(f_y\),则可得:

\[f_x=\frac{\deg_xa_x+\sum_{y\in S}f_y}{|S|} \]

但转移顺序难以处理,一个直觉是按 \(f\) 升序确定,我们需要证明不会出现 \(f_v\) 在后续降到比 \(f_u\) 小再反过来处理 \(f_u\) 的情况,只需证明加入 \(f_u\) 后 \(f_v'\) 不会比 \(f_u\) 小,后续加入的更大自然满足。

有 \(f_v-f_v'=\frac{d_va_v+\sum f_y-f_u|S|}{|S|(|S|+1)}\),\(f_v-f_u=\frac{d_va_v+\sum f_y-f_u|S|}{|S|}\),因而 \(f_v-f_v'<f_v-f_u\implies f_v'>f_u\),得证。因此我们跑 dijkstra 即可,特判 \(|S|=0\) 的情况剩下的用 \(f_v-f_v'\) 的式子更新即可。

[MXBZ2026 R10] 拓扑 / P15750 [JAG 2024 Summer Camp #3] Coins on a Tree

首先显然考虑 ExchangeArgument,比较 \(a+b,b+a\) 的字典序即可确定优劣,每轮按长度升序排序暴力扫一遍比较长度和是 \(O(n)\) 的可以做到 \(O(n^2)\)。

考虑优化,一个平凡的思路是上平衡树,是大常数 \(O(n\log^3 n)\) 有点不牛。你发现每次都只会拼在前面后面,我们考虑倍增哈希,用链表维护,向前后加入单个字符只更新 \(O(\log n)\) 个信息,合并时做启发式合并即可做到 \(O(n\log^2n)\)。

然后一个实现上的小问题就是如何比较 \(a+b,b+a\) 的字典序,在比较时启发式合并两个链表是不妥当的,你考虑如果一个串到头另一个串还没结束比不出来,就把到头的指针挪到另一个串起点,这样至多挪动两次,第三次比较还比不出来两串必然同时结束。

10.10

[MXBZ2026 R11] 春 / CF961D Pair Of Lines

前三个点必然有两个在一条线上,三种都试一下即可。

[MXBZ2026 R11] 南见山 / P15622 [ICPC 2022 Jakarta R] The Only Mode

考虑跑四遍,分别求每个权值的答案。考虑描述一个序列取这个权值为绝对众数,要求他的出现次数比剩下三个都多,我们前缀和一下做差分求点数,考虑 \(f_c(r)-f_c(l)>f_d(r)-f_d(l)\iff f_c(r)-f_d(r)>f_c(l)-f_d(l)\),那么我们对每个点维护三种差分,合法左端点就是一个三维偏序,但事实上还有下标一维的偏序,然而你发现实际上你反正求的是最小左端点,下标更大更劣无需在意。

然后一个细节是这里是严格小于号,CDQ 过程中只保证了第一维度右侧大于等于左侧,取等的情况需要特殊处理,我们开两棵线段树把等于的元素隔离出来即可。

[MXBZ2026 R11] 西廉贞 / CF1867F Most Different Tree

注意到,如果一个子树在另一侧出现过,那么它的所有子树都出现过;同理,如果一个子树没在另一侧出现过,那么他的所有祖先都不会在另一侧出现。那么容易考虑一个策略是,找到点数最小的不曾出现过的子树,把剩下的点逐个接到他的上面接成一条链,必然最优。

无标号有根树的个数是指数级别的,精细算一下本题树大小要枚到 \(15\),直接从小到大搜即可,判出没出现过显然只能大力树哈希。

10.12

P15380 闪现树 / grood

我们先考虑求出一层的叶子节点数。设计 \(f_n(h)\) 表示 \(n\) 阶树的第 \(h\) 层叶子数,考虑相当于从根开始跳 \(n\) 次,每次跳一步或两步,两步有四种方案,可得:

\[f_n(h)={n\choose h-n}4^{h-n} \]

那求一层的总点数呢,除了根以外的每个点必然由之前的某个叶子作根生成一阶树得来,记 \(F_n(h)=\sum_{i\le n}f_n(h)\),因而第 \(h\) 层的总点数实际上是 \(3F_{n-1}(h-1)+4F_{n-1}(h-2)\)。

考虑递推求 \(F_n\),有:

\[\begin{aligned} F_n(h+1)&=\sum_{i=0}^n4^{h-i+1}{i\choose h-i+1}\\ &=\sum_{i=0}^n4^{h-i+1}\left({i-1\choose h-i+1}+{i-1\choose h-i}\right)\\ &=\sum_{i=0}^{n-1}4^{h-i}{i\choose h-i}+\sum_{i=0}^{n-1}4^{h-i}{i\choose h-i-1}\\ &=F_n(h)-4^{h-n}{n\choose h-n}+4\left(F_n(h-1)-4^{h-1-n}{n\choose h-1-n}\right)\\ &=F_n(h)+4F_n(h-1)-4^{h-n}{n+1\choose h-n} \end{aligned} \]

于是即可递推。初始化 \(F_{n-1}(0)=1,F_{n-1}(1)=[n>1]\)。

P7481 梦现时刻

\[\begin{aligned} F(a,b)&=\sum_{i=0}^b{b\choose i}{n-i\choose a}\\ &=F(a,b-1)+\sum_{i=0}^n{b-1\choose i}{n-i-1\choose a} \end{aligned} \]

右式不好处理,我们再设一个 \(G(a,b)=\sum_{i=0}^n{b\choose i}{n-i-1\choose a}\),有:

\[\begin{aligned} F(a,b-1)&=\sum_{i=0}^n{b-1\choose i}{n-i\choose a}\\ &=G(a,b-1)+G(a-1,b-1) \end{aligned} \]

又有:

\[\begin{aligned} F(a-1,b)&=\sum_{i=0}^n{b\choose i}{n-i\choose a-1}\\ &=F(a-1,b-1)+G(a-1,b-1) \end{aligned} \]

因而有:

\[\begin{aligned} F(a,b)&=F(a,b-1)+G(a,b-1)\\ &=F(a,b-1)+(F(a,b-1)-F(a-1,b)+F(a-1,b-1))\\ &=2F(a,b-1)-F(a-1,b)+F(a-1,b-1) \end{aligned} \]

于是我们就可以 \(O(m^2)\) 递推得到 \(F\)。边界为 \(F(a,0)={n\choose a}\)。

#18468. 括号序列

字典序显然不好处理,我们统计上 \(t\) 的所有合法前缀,然后枚举首个不同的位置,将右括号改为左括号,记前缀左括号比右括号多 \(x\),则后缀右括号必然比左括号多 \(x\),同时视作折线任意前缀非负,考虑反射容斥。

假如剩余长度不超过 \(n\),前缀左括号比右括号多 \(a\),相当于从 \((0,0)\) 走到 \(y=x+a\) 线上且不走到线之上同时步数不超过 \(n\),所求即为:

\[\sum_{i=0}^{\lfloor\frac{n-a}{2}\rfloor} {2i+a\choose i}-{2i+a\choose i-1} \]

记 \(t=\lfloor\frac{n-a}{2}\rfloor\),\(f(i,a)={2i+a\choose i}-{2i+a\choose i-1}\),我们先对 \(f\) 应用 Pascal 递推:

\[\begin{aligned} f(i,a)&={2i+a-1\choose i}+{2i+a-1\choose i-1}-{2i+a-1\choose i-1}-{2i+a-1\choose i-2}\\ &={2i+a-1\choose i}-{2i+a-1\choose i-2}\\ &=f(i,a-1)+f(i-1,a+1) \end{aligned} \]

然后我们考虑求 \(F(t,a)=\sum_{i=0}^tf(i,a)\) 的递推:

\[\begin{aligned} F(t,a)&=\sum_{i=0}^t f(i,a-1)+\sum_{i=0}^{t-1}f(i,a+1)\\ &=F(t,a-1)+F(t,a+1)-f(t,a+1)\\ &=F(t,a-1)-F(t,a-2)+f(t,a)&\text{(上一步移项得)} \end{aligned} \]

然而两维都是 \(O(n)\) 的。然而你注意到,前缀移动一位 \(a\) 只变化 \(1\),因而 \(a\) 的总变化量是 \(O(n)\) 的,\(t\) 的总变化量也是 \(O(n)\) 的,我们考虑关于 \(t,a\) 两维做一个不分块莫队状物。

  • \(t\) 的变化是平凡的,加上或减去一个 \(f(t,a)\) 即可。
  • \(a\) 的变化也是平凡的,递推式已经给出来了,维护 \(F(t,a)\) 和 \(F(t,a+1)\) 往前往后推都可以。

因此就做完了,复杂度 \(O(n)\)。

P8367 [LNOI2022] 盒

\(val(B)\) 是好求的,记 \(p_A(i)\) 表示序列 \(A\) 的前缀 \(i\) 元素和,最小代价即为 \(\sum_{i=1}^{n-1}w_i|p_a(i)-p_b(i)|\)。

我们把贡献拆到各前缀上,若前缀 \(i\) 的前缀和为 \(s\),容易由插板法得到方案数,答案即为:

\[\sum_{i=1}^{n-1}w_i\sum_{s=0}^{S}{s+i-1\choose i-1}{S-s+n-i-1\choose n-i-1}|s-p_a(i)| \]

考虑求前缀和,记 \(f_{n,S}(i,t)=\sum_{s=0}^t{s+i-1\choose i-1}{S-s+n-i-1\choose n-i-1}\),然而直接拆绝对值成两段你会得到一个很一坨的式子,注意到 \(f_{n,S}(i,S)={S+n-1\choose n-1}\),考虑直接去掉绝对值然后对 \(s\le p_a(i)\) 的部分额外加上 \(2(p_a(i)-s)\),同时 \(s{s+i-1\choose i-1}=i{s+i-1\choose i}\) 然后这一个和式顶到头又可以卷一起得 \(i{S+n-1\choose n}\),于是我们可以把后面那个和式写作:

\[i{S+n-1\choose n}-p_a(i){S+n-1\choose n-1}+2(p_a(i)f_{n,S}(i,p_a(i))-if_{n+1,S-1}(i+1,p_a(i)-1)) \]

于是只需关心 \(f_{n,S},f_{n+1,S-1}\) 的各一项,注意到 \(i,p_a(i)\) 是单增的,两维总变化量都是 \(O(n)\) 的,考虑不分块莫队状物维护两维,\(t\) 变化是平凡的,\(i\) 变化考虑 Pascal 递推,注意第二个组合数里 \(s\) 系数是负的所以应当往上推,即 \({S-s+n-i\choose n-i}={S-s+n-i-1\choose n-i}+{S-s+n-i-1\choose n-i-1}\),可得:

\[\begin{aligned} f(i,t)&=\sum_{s=0}^t\left({s+i-2\choose i-1}+{s+i-2\choose i-2}\right)\left({S-s+n-i\choose n-i}-{S-s+n-i-1\choose n-i}\right)\\ &=f(i-1,t)+\sum_{s=0}^t{s+i-2\choose i-1}{S-s+n-i-1\choose n-i-1}-\sum_{s=0}^t{s+i-2\choose i-2}{S-s+n-i-1\choose n-i} \end{aligned} \]

发现两个下指标都恰好差 \(1\),一个神秘套路是考虑构造一个辅助数组 \(g(s)\) 满足 \(g(s)-g(s-1)={s+i-2\choose i-1}{S-s+n-i-1\choose n-i-1}-{s+i-2\choose i-2}{S-s+n-i-1\choose n-i}\),这样就可以消掉中间项,还是上 Pascal,我们构造两项使得其中一项在 \(g(s)\) 内为求和结果,另一项在 \(g(s-1)\) 内为求和结果,展开后抵消一下即可得到所求。

\[g(s)={s+i-1\choose i-1}{S-s+n-i-1\choose n-i}\\ g(s)-g(s-1)={s+i-2\choose i-2}{S-s+n-i-1\choose n-i}-{s+i-2\choose i-1}{S-s+n-i-1\choose n-i-1} \]

和需求取反了,影响不大,于是可得:

\[f(i,t)=f(i-1,t)-g(t)=f(i-1,t)-{t+i-1\choose i-1}{S-t+n-i-1\choose n-i} \]

于是我们终于可以推来推去了。注意循环是从 \(i=1\) 开始的而 \(i=0\) 时取值不一定为零,因此初始化时应 \(i\gets 1,t\gets 0\)。

10.13

[MXBZ2026 R12] 区间平移

每个区间在值域上可以转化为四个差分的差分,跑一遍即可。喜欢 map 的小朋友们你们好呀喜欢我们 \(100\to 50\) 吗。离散化即可。

[MXBZ2026 R12] 连号标记

显然考虑钦定然后二项式反演,钦定的时候一个父亲只能钦定至多一个儿子,拓扑序计数公式是 \(\frac{n!}{\prod sz}\),我们把 \(sz^{-1}\) 系数下发到转移过程即可,注意统计的是缩点后的信息。

[MXBZ2026 R12] 信号汇聚 / P12585 「KTSC 2019 R1」广播站

相当于要求生成一棵树,树边权为点权差的平方,显然每棵子树都是一个连续区间不劣。容易考虑一个 \(f(l,r,h,rt)\) 表示区间 \([l,r]\) 深度至多为 \(h\) 根在 \(rt\) 的方案数,然后你发现这个 \(rt\) 可以去掉,因为子树不可能越过根,可以直接拆成左右两部分,故设计 \(f(l,r,h,0/1)\) 表示根在左或右端点即可。

考虑转移,首先一个点肯定有多个子树,如果尝试处理一个“一段区间是多个子树的并”的东西将会很难做,因为你显然关心根的权值。那你不妨就枚举最左边或最右边的子树转移啊,枚举儿子 \(k\) 再枚举他的子树边界 \(t\),比如处理 \(f(l,r,h,1)\),显然有:

\[f(l,r,h,1)=\max_{k=l}^{r-1}\max_{t=k}^{r-1}f(l,k,h-1,1)+f(k,t,h-1,0)+f(t+1,r,h,1)+(x_k-x_r)^2 \]

开一个辅助数组把两重枚举拆开即可。复杂度 \(O(Tn^4)\)。

[MXBZ2026 R12] 货运通道 / #18293. Truck and Queries

维护一个 \(r_i\) 表示为了合法到达终点到 \(i\) 至少需留下的物量,有 \(r_i=\max(0,r_{i+1}-A_i)\),非法当且仅当 \(k<r_1\),否则只需保证 \(b_i\ge r_i\),与 \(k\) 无关。

答案即为 \(\sum\max(0,r_{i+1}-b_i)\),考虑一次一操作 \((x,y)\),只可能会对 \([1,x]\) 的 \(r\) 造成影响,从后往前提升,若原本 \(r_{i+1}-A_i\le 0\) 就可以停了,如果从正数变成非正数的话后续修改权值会发生变化,注意到每个数只会变化一次所以可以直接每次线段树二分搜下去,\(\max(0,r_{i+1}-b_i)\) 暴力处理变化元素维护,每个数只会被处理一次。容易用线段树实现这个东西。

然后,会爆 long long,要开 __int128。

10.14

[MXBZ2026 R13] 梦境

操作一不太好处理,但你发现后面都是单点修改,因此每次直接找下一个 \(1\) 均摊次数是 \(O(n)\) 的,写一个线段树维护即可,连续段长度上 set 之类然后做成区间覆盖,复杂度 \(O(n\log n)\)。

[MXBZ2026 R13] 黄金矿工

你发现对手的操作有效仅当对于一个 \(01\) 列你选了 \(1\),此时他交换会给你带来 \(-1\) 的贡献。

分讨两种情况,一种是不选这种东西,那么每列贡献一定,\(00\) 只选一个代价 \(-1\),\(01\) 必然全选代价 \(0\),\(11\) 必然全选代价 \(2\),求一个最大子段和即可。否则,我们不妨钦定减去 \(-2m\),则只需选出一个连通块最大化 \(1-0\) 的个数,写一个平凡的 DP 状压最后一列的状态即可。复杂度 \(O(n)\)。

[MXBZ2026 R13] 惊喜 / CF809E Surprise me!

首先考虑求 \(\varphi(n)\),设 \(n=\prod_{i=1}^sp_i^{k_i}\),则:

\[\varphi(n)=n\prod_{i=1}^s\frac{p_i-1}{p_i} \]

于是可以推出:

\[\varphi(xy)=\varphi(x)\varphi(y)\frac{\gcd(x,y)}{\varphi(\gcd(x,y))} \]

如果这个都不会就不用往后想了,比如我。

显然考虑莫反,设计:

\[f(d)=\sum_{d=\gcd(a_u,a_v)}\varphi(a_u)\varphi(a_v)\mathrm{dis}(u,v)\\ g(d)=\sum_{d\mid a_u,d\mid a_v}\varphi(a_u)\varphi(a_v)\mathrm{dis}(u,v) \]

则有 \(g(d)=\sum_{d\mid D}f(D)\iff f(d)=\sum_{d\mid D}g(D)\mu(\frac{D}{d})\)。答案即为 \(\sum \frac{d}{\varphi(d)}f(d)\)。

枚举 \(d\) 求 \(g(d)\),点权是排列,因此 \(d\mid a_u\) 的点 \(u\) 总量是 \(O(n\log n)\) 的,建虚树每次直接跑即可。复杂度 \(O(n\log^2n)\)。注意建虚数后会有 \(d\nmid a_u\) 的点在树上,不能算这些点的贡献。

[MXBZ2026 R13] 行走于真实之道 / CF1895G Two Characters, Two Colors

这个东西是可以网络流建模的。我们对每个 \(1\) 连边 \((S,i,r_i),(i,T,b_i)\),对每个 \(0\) 连边 \((S,i,b_i),(i,T,r_i)\),然后每个 \(1\) 向他后面的 \(0\) 连 \(1\) 的流量,用 \(\sum(r+b)\) 减去最小割即为答案。

考虑模拟网络流,不妨先让每个 \(i\) 从源点到汇点流 \(\min(r_i,b_i)\) 的流量,那么有一些 \(1\) 会有多出的源点来的流量,有一些 \(0\) 会有空闲的去汇点的流量,考虑给他们匹配,注意到每个 \(1\) 都与整个后缀连了边,不妨从前往后扫一遍,遇到 \(1\) 就加入集合,遇到 \(0\) 贪心地把最大的几个元素消耗掉即可,无需考虑回撤操作,平衡树维护即可。

10.15

#6398. Puzzle: Tapa

每个线索周围只能删至多一个点。不妨先忽略行列均为偶数的块,剩下的有效块均连接两个点,可以把删除视作匹配,特殊地边界上的点不能和中间点匹配。可以证明这样是充分的,因为如果选了一个被忽略的块,必然可以等效替代为两个匹配。

#14979. Shiratama

做过。

10.17

CF1207E XOR Guessing

第一次输出 \(1\sim 100\) 得到后 \(7\) 位,第二次输出 \((1\sim 100)\ll 7\) 得到前 \(7\) 位,然后就拼出答案了。

P9599 [JOI Open 2018] 木琴 / Xylophone

首先只问相邻两个可以确定二者差值,但并不清楚谁高谁低,注意到题面保证了最大值在最小值之后,一个想法是搞出折线,然后依赖这一性质便能唯一确定序列。这样只需确定相邻两段直线是朝着同一方向还是不同方向,你发现问相邻三个即可确定其内两条直线的方向,因而只需要问不超过 \(2n\) 次。

10.18

P17729 [SCP-J 2026] 进位 / carry

值得注意的是,\(a,b\) 相加二进制下发生的进位次数为 \(\mathrm{popc}(a)+\mathrm{popc}(b)-\mathrm{popc}(a+b)\),而不知道这个的话本题就只能做到 \(O(n\log n)\) 比如我,如果每次都这么判会严肃 TLE,但注意到很多次判定实际上是要求没有进位,这等价于 \(a+b=a\operatorname{OR}b\),因此就能通过,不过用 \(\mathrm{popc}\) 就能做到严格 \(O(n)\)。

P17730 [SCP-J 2026] 数组 / array

考虑把贡献全都放到 \(a_0\) 序列上面,区间求和是平凡的,枚举 \(a_0\) 上贡献的位置 \(x\),其对于 \(a_x\) 上一个位置 \(y\) 的贡献系数形如一个 \({x-1+y-x\choose x-1}\),前缀和预处理此系数一下即可;区间修改也是平凡的,实际上相当于在 \(l,r+1\) 进行单点修改,向下修改系数形如杨辉三角每行奇正偶负(\(r+1\) 反过来本质相同),枚举 \(a_0\) 上被影响的位置 \(x\) 算一下即可。复杂度 \(O(nq)\)。

P14596 [COCI 2025/2026 #2] 比赛 / Natjecanje

两两匹配起来不劣,然后是个一般图匹配,上模拟退火随随随就过了。

10.20

锦里客流

显然各决策有凸性有一车贪心做法,比如对每个右端点维护其当前左端点指针,然后堆维护一下当前最优决策之类的。

川剧复演

往纯容斥方向思考会发现貌似没有什么前途。考虑 DP,设计 \(f(i,j)\) 表示考虑到 \(i\) 之前最近的重复的颜色在 \(j\),那么 \(j\) 后面的必然各不相同,新的元素选 \(j\) 后面的会更新 \(j\) 否则 \(j\) 不会更新,然后就能写成矩阵形式,比较卡常。

山城巷图 / P7880 [Ynoi2006] rldcot

不妨钦定 \(i\le j\),则只需满足 \(i\ge l\land j\le r\),对 \(r\) 扫描线,对每个 \(\mathrm{dep}(\mathrm{lca})\) 维护其最大的 \(i\),则只需查询 \(i\ge l\) 的个数,容易实现,直接做每次需更新 \(O(n)\) 个点对复杂度 \(O(n^2\log n)\),需要优化。

考虑支配对,枚举 LCA 做 dsu on tree,对每个轻子树内点找其他子树内其编号的前驱与后继,则点对数是 \(O(n\log n)\) 的,只把这些点对扔进去跑扫描线即可做到 \(O(n\log^2n)\)。

迷星叫 mayoiuta

显然考虑处理出每个点被覆盖的次数然后直接树剖维护修改即可。

考虑点分治,对每个分治中心处理经过其的路径,枚举一个端点可以树状数组得到合法的另一个端点数量,做一次到根的链加即可,注意分治中心的贡献为原来两倍需除以二,同时特殊处理一下其自己到自己的路径。

在 NOIP 模拟赛 T1 放这一坨东西组题人一定觉得很有意思吧。

假面惊梦 masquerade / P4654 [CEOI 2017] Mousetrap

容易得到二者策略形如,后手往上走一段后向下走到某个叶子等死,先手先对他进行拦截,在他走到叶子后先把路径上的分支边剪完然后修复后手到根上被走过的路径,因为后手倘若走进一个分叉代价必然更大。

首先容易对每个点处理出向下走到他之后双方最优策略下最小代价,但是往上走到什么地方是不好做的。考虑二分转为判定性问题,这样从下到上先手必须把每个步数过大的子树剪掉,从下到上模拟一遍即可。

断章的诗 utakizuna

我们对 A 串建 ACAM,然后拿 B 串在上面跑,可以对 B 串的每个位置得到哪些 A 串前缀可以在这里结束匹配上。同理翻转再做一遍可以得到哪些 A 串后缀可以在这里开始匹配上。

枚举 A 串前缀,我们关心其能匹配上的后缀数量。在第一棵 fail 树上,其子树内被标记的位置都是他可以匹配上的 B 串位置,所求即为这些位置在第二棵 fail 树上的祖先集合大小。

我们 dsu on tree 处理第一棵 fail 树,每次更新树剖做到首个已做过的祖先,复杂度 \(O(n\log^3n)\) 有点不太牛,考虑线段树合并,这样树剖部分复杂度就是 \(O(m\log^2 n)\),合并部分复杂度是 \(O(n\log^2n)\),复杂度两只 \(\log\)。

P8528 [Ynoi2003] 铃原露露

直接对区间做这个判定是不方便的。考虑对每对 \(x,y,z=\mathrm{lca}(x,y)\) 求出其影响的区间,显然可以分讨得到两个矩形。

考虑支配对,同一个 \(z\) 包含了其他区间的 \([a_x,a_y]\) 被支配,同样做 dsu on tree 即可将矩形个数压到 \(O(n\log n)\)。

那么现在就是要查没有被覆盖的点对数,做一个历史信息和即可。\(O(n\log^2n)\)。

10.21

[MXBZ2026 R14] 传递能量

首先对一种合法情况下所有元素同时多操作一次即可使各元素仍相同且终值减一,因此合法性具有可二分性,而总操作次数等于原元素和减去最终元素和,因此最终元素越大操作次数越少。然而其实不用二分,我们容易列出 \(n\) 个关于操作次数的方程,形如 \(k_{i-1}-2k_i=x_i\),易知要么不存在合法解要么只有唯一一组解,那么我们钦定终值为 \(1\) 尝试跑出唯一解,然后每个 \(k\) 减去最小 \(k\) 即可得到最优局面。

解这个方程显然有点大,不妨对一个足够大的质数取模,操作次数显然不超过元素和,因此随便选一个 \(10^{18}\) 级别的质数作模数都可以,只要最后解出来所有 \(k\) 非负且总和恰为要求值就有解,否则无解。复杂度 \(O(n)\)。

[MXBZ2026 R14] 分数

扫描线没有前途,分治和笛卡尔树其实都可做,但前者显然并不优美。考虑在笛卡尔树上启发式合并,直接做需要对大子树做高维前缀和,复杂度 \(O(n\log n+nV\log V)\),太不牛。考虑对值域折半,每次大力单点插入,即可做到 \(O(n\log n\sqrt V)\),可以通过。

[MXBZ2026 R14] 数组

矩阵走走走没有任何意义,对两个数组做差分则各自单增,相当于闵和每次选一个较小的差分值加上来即可,等价于把两个差分序列归并之后倒数第 \(i\) 个元素带 \(len-i+1\) 的系数求和。显然考虑每次暴力把第一个序列中的元素插入第二个序列中,然后和我一样奶龙的人会真的写一个平衡树去做合并再写两种标记然后得到一个很复杂的下传方案最终 TLE 掉。对第二个序列建一个线段树,插入一个元素时,只需要二分找到他的排名,然后对比他小的元素求一次和加入答案,他自己的贡献系数等于第二个序列比他大的元素和第一个序列比他大的元素,可以直接算掉,查询根本无需对序列进行任何修改。我是奶龙。

[MXBZ2026 R14] 篮子

考虑描述一个合法保留颜色集合,等价于描述合法删除颜色集合 \(S\)。对 \(S\) 中同时存在的 \(x\to x-2\) 和 \(x\to x+k\) 连边,若存在环其必然存在一个颜色仍被保留,否则可以按拓扑序删,因此无环是充要的。

若 \(2\mid k\),分别处理奇偶数,等价于不能连续选 \(k/2+1\) 个数,直接 DP 即可。

若 \(2\nmid k\),把奇偶数排成两列(注意题面要求不能删 \(1\) 因此奇数自 \(3\) 始),直接连边很丑,奇数在右边列我们将其向上提 \(\lfloor k/2\rfloor\) 格,这样从左到右的边均水平,右侧点向比他低 \(k\) 高度的左侧点连边,这样环的最小单位形如从一个左侧点往上走,然后右行,然后再往上走,然后一步回到起点。

设计 \(f(i,j,k)\) 表示当前考虑到第 \(i\) 层,左侧点能向上走到最远的横叉边右行再往上走到的最远的右侧点在第 \(j\) 层,第 \(i\) 层的右侧点往上能走到第 \(k\) 层的方案,转移只需看该层两点的存在情况即可,是平凡的。复杂度 \(O(n^3)\)。

10.22

CF702F T-Shirts

按质量降序价格升序排序,则策略为顺序扫描能买就买。考虑一个暴力 DP:

\[f_{i,j}=\begin{cases}f_{i+1,j}&,j<c_i\\f_{i+1,j-c_i}+1&,j\ge c_i\end{cases} \]

注意到新的 \(f\) 形如将原来的 \(f\) 复制一遍加一覆盖掉一个后缀,容易可持久化平衡树实现。然而写 FHQ-treap 复杂度是假的,因为你复制点的时候需要维护树形态保留原随机权值,因此权值不具随机性,合并分析不出来。当然我不知道好不好卡。

然后问 DS 给了一个叫 RBST 的东西,就是每次合并以 \(\frac{sz_a}{sz_a+sz_b}\) 的概率以 \(a\) 为父亲,它声称这种合并方式在数学期望上等价于将两棵树的所有节点放在一起,然后完全随机地打乱,再重新建一棵二叉搜索树,期望树高 \(O(\log n)\),因为 RBST 具有马尔可夫性。

然后这个做法 MLE。卡不进去。我没招了。

另一个做法是离线,升序排序所有询问并用平衡树维护询问序列,每个物品买的人必然是当前一个值域后缀,对剩余权值在 \([0,c)\) 内的不管,\([c,2c)\) 内的暴力插入到前面,\([2c,+\infty)\) 的打一个区间减 tag 不改动顺序,暴力插入的每次权值减半,仍然平衡树维护复杂度 \(O(n\log n\log V)\)。

CF444C DZY Loves Colors

颜色段均摊板子。

ABC256Ex I like Query Problem

注意到没有二操作的话,一个点最多被操作 \(\log V\) 次就会变 \(0\)。因而考虑势能,若区间所有元素均相同是平凡的,否则直接搜下去大力修改,摊下来复杂度两个 \(\log\)。

P2824 [HEOI2016/TJOI2016] 排序

任意时刻区间必然可以分为若干个内部有序的区间,这些区间的状态可以直接用一个升降序 tag 和内部元素集合表示。考虑对每个区间维护权值线段树,一次排序就是分裂 \(O(1)\) 个区间之后对连续一段区间执行线段树合并。而对于一个排好序的区间,分裂出来的必然是值域上一段前缀或后缀,容易在 \(O(\log n)\) 的复杂度内实现,这部分新建的点数是 \(O(m\log n)\) 的,因此复杂度是 \(O((n+m)\log n)\)。

P13693 [CEOI 2025] Equal Mex

注意到这个数必须不存在,然后注意到这个数必然是最小的不存在的元素 \(x\)。那么要求变为划分子段,使得小于 \(x\) 的元素在每个子段中均出现过。那么只需要找到最大的合法 \(k\) 即可。

考虑极小 mex 区间,扫描线求的同时也容易得到各查询区间的 mex 值,注意到极小 mex 区间无包含关系,那么实际上就是在被查询区间完全包含的该 mex 值的极小 mex 区间中选出尽可能多的无交区间数量,容易倍增贪心处理。

P4198 楼房重建

单侧递归板子。

P9130 [USACO23FEB] Hungry Cow P

也是单侧递归,对每个区间维护溢出个数,上传时将左区间溢出的贡献递归进右区间计算,分讨能不能把左子区间填满即可。

10.23

P9990 [Ynoi Easy Round 2023] TEST_90

扫描线,每次一个区间异或,然后就是历史信息和板子。

CF1340F Nastya and CBS

考虑线段树,一个区间如果内部存在一对相对的左右括号匹配不了就无解了,因此抵消完之后必然形如一个前缀的右括号拼上一个后缀的左括号,对这个做哈希,合并判定是否匹配即可。

然而实现上一个问题就是如何维护每个区间的串的哈希值,直接维护的话修改复杂度会爆掉。考虑单侧递归,每个区间维护其串的左括号序列和右括号序列整个的哈希值,取一段前缀的时候递归下去,左侧长度不满就进去,否则进右侧,长度减去左侧长度再加上左侧右括号抵消掉的长度,得到的返回值再除去本应被抵消掉的哈希部分即可。复杂度俩 \(\log\)。

看起来就很复杂,还是分块好写,嘟嘟嘟。

P11622 [Ynoi Easy Round 2025] TEST_176

考虑离线扫描线,遇到一个 \(l\) 就把 \(x\) 加进去,每次操作相当于把 \(<\lfloor a/2\rfloor\) 的元素提出来取负加上 \(a_i\),涉及平衡树有交合并,势能分析出来是两个 \(\log\),注意需要手动合并相同点否则树高在有交合并过程中会炸掉。

CF932F Escape Through Leaf

李超树合并板子。

LOJ176 动理序列最值

KTT 板子。

CF1830F The Third Grace

设计 \(f(i)\) 表示考虑到 \(i\) 钦定最后一个元素选了 \(i\),暂时不算 \(i\) 的贡献的最大贡献值,转移为 \(f(i)=\max_j f(j)+p_j\#\{k\mid l_k\le j\le r_k<i\}\),扫描线,每走出一个 \(j\) 就把 \(r_k=j\) 的线段贡献算上,对每个 \(i\) 维护价值,发现就是 KTT 维护的东西,遂做完。

10.24

P5693 EI 的第六分块

不带修维护区间最大子段和是平凡的,对每个点维护内部最大区间 \(m\)、含左端点最大区间 \(l\)、含右端点最大区间 \(r\)、区间和 \(s\) 即可。考虑维护区间加操作,如果各信息最优区间不变的话就是答案直接加上 \(len\cdot\Delta\),于是我们使用 KTT,于是做完了。

P6792 [SNOI2020] 区间和

区间取 max 是经典 SegBeat,待修区间最大子段和就是 P5693,KTT 本质上是线段树所以直接做法拼一起即可。具体地,直线斜率修改为区间内最小值个数即可。

10.26

P4689 [Ynoi Easy Round 2016] 这是我自己的发明

考虑放到 dfn 序上,每个子树都是一个区间,差分一下变成前缀,跑莫队即可。

P5355 [Ynoi Easy Round 2017] 由乃的玉米田

见小清新人渣的本愿,加了一个商,比根号大可以暴力枚举除数,比根号小的话就不好处理了,虽然只有 \(O(\sqrt n)\) 种,但是莫队单次移动复杂度显然不能上 \(O(\sqrt n)\)。

怎么办呢,抛弃莫队(对于小于根号的商查询,我们枚举商跑扫描线,对每个点维护他左侧最近的与他成所需关系的位置即可,维护一下前缀最大值就做完了。

整体复杂度 \(O(n\sqrt n+\frac{n^2}{w})\)。

P4688 [Ynoi Easy Round 2016] 掉进兔子洞

相当于求每个数在三个区间中的最小出现次数之和。显然是不好维护的,考虑用 bitset 整一下。但直接做的话只能确定三个区间中同时出现的颜色种数而非个数,然而我们大可将每个颜色分出出现次数段,对每个颜色都把其对应的那一段位置长为出现次数的前缀设成 \(1\),这样求交就可以得到颜色个数了。

不过空间有点小炸,给询问分若干组每组单独跑一遍上述算法即可。

P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II

考虑莫队,需要查询当前区间内比某值大或小的元素个数,直接做是 \(O(n\sqrt n\log n)\) 的,考虑优化,考虑二次离线,相当于 \(O(n\sqrt n)\) 次区间查询,差分一下做成前缀查询,扫描线用 \(O(\sqrt n)-O(1)\) 值域分块维护一下即可做到 \(O(n\sqrt n)\)。

P9986 [Ynoi2079] r2pspc

首先有效位数是 \(O(n+\log n)\) 的,可以先离散化。以及每次暴力进位均摊下来复杂度是 \(O(n)\) 的。

考虑莫队,然而回撤的复杂度并不能均摊分析。考虑回滚莫队,但是左端点移动也摊不下,只能保证右端点移动复杂度在 \(O(\frac{n^2}{B})\)。

考虑处理左端点的移动,我们按块内出现的数将值域划分为若干块,则修改只会在块尾进行,注意到一个块尾 \(x\) 向下一块中 \(x+\log n\) 的贡献不超过 \(1\),因而考虑对每个块用一个数维护前 \(\log n\) 位的值和往后第一个为 \(0\) 的位置即可处理前面块的进位,这样即可做到 \(O(1)\) 修改 \(O(B)\) 查询,也就是 \(O(mB)\) 的复杂度。均衡一下做到 \(O(n\sqrt m)\) 。

实现细节上,右端点修改直接大力维护,左端点修改时不实际进行,在对应块尾处储存进位次数,然后查询扫过去的时候再计算贡献即可。

P5309 [Ynoi2011] 初始化

考虑根号分治, \(x\ge \sqrt n\) 的时候直接暴力枚举所有位置修改即可,考虑到要区间查这里写一个 \(O(1)-O(\sqrt n)\) 的分块 ,考虑 \(x\le \sqrt n\) 的情况,注意到保证了 \(y\le x\),我们把这些操作按 \((x,y)\) 存下来,查询的时候枚举所有的 \(x\),对 \(y\) 做区间求和,同余域上把整段直接求和算掉,剩下两个散段区间求和即可,注意到这些总长均不超过 \(\sqrt n\) 修改的时候 \(O(\sqrt n)\) 更新前缀和 \(O(1)\) 查询,即可做到 \(O(n\sqrt n)\)。

P7811 [JRKSJ R2] 你的名字。

考虑根号分治。对 \(k\le B\) 的,离线下来每个 \(k\) 跑一遍即可,每次开个线段树做到 \(O(nB+m\log n)\)。

对 \(k\ge B\) 的,不妨枚举 \(k\) 的倍数 \(ak\),求区间内不小于 \(ak\) 的最小值,降序双指针扫描动态进行 \(n\) 次元素插入,则拆成了 \(O(\frac{mV}{B})\) 次区间查最小值,为了节省空间这里考虑枚举 \(ak\) 之后去枚举因数而不把所有查询存下来。

考虑一个类似 \(O(B)-O(1)\) 的算法,容易想到分块,不过区间最小值无法简单前缀和处理,考虑猫树结构,对 \(O(\frac{n}{B})\) 个块建猫树,每次插入重构到根路径节点复杂度是 \(O(\frac{n}{B})\) 的,符合条件。

10.27

[MXBZ2026 R15] 次大值

考虑倒着做,最终情况最大值与次大值均一定(记得判掉 \(b_n\ne n-1\) 的非法情况),考虑去掉最后一个元素,若次大值变化,则这个元素要么是最大值要么是次大值,无论哪一种留下来的就成了新的最大值没有影响,因此乘上一个 \(2\) 的系数即可。否则当前元素小于当前次大值,贡献延后,开一个 \(cnt\) 记录这样的元素数量,次大值变化的时候把中间的空位填上去,最后还没填上的直接一个阶乘就算完了。到最后第一个元素和第二个元素必然是最后的最大值和次大值,不过顺序不一定,额外乘一个 \(2\) 即可。

[MXBZ2026 R15] 零边

首先是主播赛时的 \(4\text{k}\) \(O(n\log^2 n)\) 过不去做法,考虑只加不删和只删不加都是好做的,前者树形态一定你写一个树剖大力维护即可,删边打标记将每个连通块当前特殊点信息存在块内最浅的点上,后者你对每个特殊点开一个可并堆存储所有出边,然后我们考虑线段树分治,后者显然不好撤销,但前者看上去就很好撤销,于是就写完了。

事实证明主播单纯忘掉了还有 Kruskal 重构树这种东西。显然一条树上边如果两侧都有团内点他就不必要加,因此考虑建出 Kruskal 重构树,那么就是总权和减去为关键点 LCA 的点权和。注意到关键点均为叶子,按 dfn 排序后相邻两两求 LCA 即可,拿一个 set 动态维护就做完了,复杂度一个 \(\log\)。

[MXBZ2026 R15] 堆换 / P4785 [BalticOI 2016] 交换 (Day2)

容易考虑贪心,顺序处理,考虑根左儿子右儿子三个点之间的交换,若根最小必然不发生交换,若左儿子最小必然只换左儿子,否则左儿子换不换是不好确定的,也就是说左儿子和右儿子可以在原本左儿子的权值和原本根的权值中选一个。

那么考虑先不决策,开一个新点表示 \(a/b\) 然后把权值赋成这个,类似 Kruskal 重构树那样合并两个点就开一个新点,这样决策时相当于取子树最小值,但你发现这么搞每个点可以有两个父亲,就很神秘。存在做法继续延伸下去但我没想。

神秘地,我们考虑对各权值建树,然后给每个点一个指针指向树上某点,表示他可以取这个点的祖先,这样多一个选择的时候只需要把左儿子的权值接在父亲权值下面,然后左右儿子同时指向左儿子权值即可。注意到因为是完全二叉树因此树高是 \(O(\log n)\) 的可以暴力跳。但是每次直接取最小的祖先还是会有问题,就可能一个子树把上面的祖先取完了另一个子树不够取了,考虑给每条树边一个往上取的次数限制,你发现只需要在把左儿子权值接在父亲权值下面的时候将这条边次数限制设成 \(1\) 即可,非常好写。

[MXBZ2026 R15] 树跃 / P15374 树上睡觉 / sleep

注意到大可钦定先统一往上跳再往下走,因为需要代价因此可以把一次睡觉和一次跳跃合并到一起,以 \(2\) 的代价往上跳 \(b_k-1\) 步。显然叶子不准跳。

首先每个点往上跳的过程是本质相同的,考虑先处理出 \(f(i)\) 表示往上跳 \(i\) 步的最小代价,然而注意到跳的时候必须保证祖先存在,不过其实不影响,只要保证树高不小于每一步 \(b\),超出的部分可以视作预先睡到下面再开跳,这样只要终点在树内就可以。先只考虑往上跳,然后从高往地取后缀 \(\min\) 状物即可。往上跳步长和不超过 \(2\) 倍树高即可,否则因为每步不超过树高故不优。

那么 \(u\to v\) 的代价即为 \(f(\mathrm{dep}(u)-\mathrm{dep}(\mathrm{lca}(u,v)))+\mathrm{dep}(v)-\mathrm{dep}(\mathrm{lca}(u,v))\),吗,并不是,因为题目给出了一组树链剖分,跳出这条链就回不来了,所以不能直接这么做。不过我们关心 \(\mathrm{lca}(u,v)\) 所在链链头,将求 \(f\) 的过程中的上界改为链头高度,跑出来的 \(f\) 就是对的了,所有链总长为 \(n\) 所以大可对每条链求一遍 \(f\)。

那么我们枚举 \(u\) 然后大力跳链,跳到一条链就处理终点在这条链上的贡献,题目条件天然带长剖性质,因此每个点最多跳 \(O(\sqrt n)\) 次。最终复杂度 \(O(nm+n\sqrt n)\)。

#12405. Path Killer

一个局面被删空的操作次数,等于所有路径被删的时刻的最大值,我们做差分,对每个时刻求仍有路径存在的概率,求和即可。

容斥求全部删完的概率,不妨对每个 \(j\) 求出所有操作共覆盖了恰 \(j\) 个点删完了所有路径的方案数(容易转概率),设计 \(f(i,j,k)\) 表示考虑到子树 \(i\) 子树内选了 \(j\) 个点仍存在的路径最深到 \(k\) 结束,第二维可以类树上背包分析,第三维再前缀和一下,转移复杂度 \(O(n^3)\)。现在所求变为:

\[1+\sum_{i=1}^{\infty}\sum_j\frac{{n\choose j}j!{i\brace j}}{n^i}(1-f(1,j))=1+\sum_j\frac{n}{n-j}(1-f(1,j)) \]

于是就做完了。

10.28

[MXBZ2026 R16] 跷跷板

考虑贪心,去移动权重最大的,但是要求相对顺序不变,因此碰上另一个点就合并到一起,一坨的价值视作总权重除以点数,每次贪心选最大的一坨即可。

[MXBZ2026 R16] 命题演算

神经模拟题,所有操作都是枚举 \(2^T\) 种可能然后 \(O(L)\) 直接求。因为展开的需要,我们考虑建立合并树状物,叶子是所有变量,每个点拆点为取反与否两种,每次运算就开一个新点,把两个儿子设做两侧对应点,同样处理该运算取反后展开的结果,是容易的,建出来是一个 DAG,点数是 \(O(L)\) 的,建树过程就正常维护两个堆模拟,注意左合并的运算要钦定左边的先做建出来顺序才是对的。

[MXBZ2026 R16] 安检门 / P14373 [JOISC 2018] 安全门 / Security Gate

考虑如何判定一个 \(S'\) 是合法的,也就是可以通过一次区间取反得到一个合法的 \(S\)。画出折线图,按取反区间划分成三段,左段要求全部非负,右段要求 \(n\) 所在位置高度 \(h_n\) 为最小值,中间段要求 \(h_r-h_{l-1}=\frac{h_n}{2}\),同时最高点翻下来仍非负,也就是不超过 \(2h_{l-1}\)。

考虑分讨是否存在 \(h_i< 0\) 以及 \(h_i<h_n\)。

  • 若均不存在,则已经合法,直接计数即可。

  • 若其中一者存在,不妨假设 \(h_i<0\),否则可以全局取反并翻转。记首次出现负数位置为 \(p\),则必然有 \(l\le p\),同时由于 \(h_i\ge h_n\),因此只需满足 \(\forall i\in [l,r], h_i\le 2h_{l-1}\land h_r-h_{l-1}=\frac{h_n}{2}\) 即可。

    此时有 \(h_n\le h_r<h_{l-1}\),因此对任意一个 \(l\) 必然可以找到合法 \(r\) 满足 \(h_r-h_{l-1}=\frac{h_n}{2}\),我们只需考虑 \(h_i\le 2h_{l-1}\) 的限制,显然取 \([0,p)\) 中最大的 \(h_{l-1}\) 作为起点不劣,再找到最近的合法 \(r\) 判定即可。

    我们枚举 \(p\),左侧部分维护最大高度即可,\(r\) 在 \(p\) 之前的话只需 \(h_r\ge 0\),否则要求 \(\forall i\in (p,r],h_i\le 2h_{l-1}\iff h_i-h_n\le 2(h_{l-1}-\frac{h_n}{2})\),同时 \(h_r-h_n=h_{l-1}-\frac{h_n}{2}\),枚举 \(h_{l-1}-\frac{h_n}{2}\) 倒序 DP 记录是否找到了 \(r\) 即可。

  • 若两者同时存在,我们再找到最后一个小于 \(s_n\) 的位置 \(q\),则 \(p>q\) 必然非法,需要满足 \(l<p<q<r\)。

    此时有两种情况,要么取 \([0,p)\) 内的最大值作为 \(h_{l-1}\),要么取 \((q,n]\) 内的最大值为 \(h_r\),具体决策并不好处理,我们不妨正着倒着都做一遍,然后减去算重也就是 \(\max_{i\in (q,n]}h_i-\max_{i\in[0,p)}h_i=\frac{h_n}{2}\) 的情况,然后 DP 过程和上一种类似,再开一维记录是否找到 \(q\) 即可。

复杂度 \(O(n^3)\)。不好评价,鉴定为主播菜了。

[MXBZ2026 R16] 精彩区间 / P11947 [KTSC 2025] 可爱区间 / maxsum

首先显然只需 \([l,r]\) 取 \(B\)、剩下的取 \(A\) 去考虑即可。描述合法条件:

  • \([l,r]\) 的子段权值均不超过 \([l,r]\),等价于任意前后缀权值非负。
  • \([l,r]\) 左侧或右侧相邻的任意长段权值均非正。
  • \([l,r]\) 外的子段权值均不超过 \([l,r]\)。

第三个限制难以处理,但实际上可以直接考虑 \(A\) 的全局最大子段和,因为满足第一个限制,完全在 \([l,r]\) 内的必然比他劣,再结合第二段限制,有交的部分必然也比他劣,因此直接考虑全局最大子段和即可。

考虑 \(B\) 前缀和 \(s\),则第一条限制等价于 \(s_r\) 是 \(s_{l\sim r}\) 的最大值、\(s_{l-1}\) 是 \(s_{l-1\sim r-1}\) 的最小值,记 \(A\) 序列最大子段和为 \(M\) 则第三条等价于 \(s_r-s_{l-1}\ge M\),第二条对每个点预处理出 \(A\) 序列最大前后缀和即可。

我们对 \(r\) 扫描线,那么合法 \(l\) 必然在首个比 \(s_r\) 大的位置之后,关心 \(s_{l-1}\) 最小限制,同样地其存在时刻必然是个区间,更进一步的你发现各个时刻合法 \(l\) 实际上是一个单调栈结构,那么满足 \(s_r-s_{l-1}\ge M\) 的必然是一个前缀,可以在线段树上二分处理。那么对于本题只需要写一个历史和就做完了。

10.29

[MXBZ2026 R17] 交点

比较平凡,维护每个对角线的条数,开两个线段树维护两种对角线数量即可,交点为正就是一个前、后缀查询,然后 \(x\) 轴上交点特判一下即可。

[MXBZ2026 R17] 剥核

容易考虑对每个点维护其被删除的时刻 \(k\),记作 \(a_i\),加边实际上是不好处理的,我们考虑倒序删边,那么删除 \((u,v)\) 时,只可能影响 \(a_i=t=\min(a_u,a_v)\) 的点,更大更小的均不影响。我们再对每个点维护 \(dg_i=\#\{j|\exists(i,j)\land a_j\ge a_i\}\),删边更新两点 \(dg\) 然后做 BFS 不断把 \(a=t\land dg<t\) 的点降级,降级后枚举 \(a_j=a_i'\) 的邻点把 \(dg_i\) 加到新值,然后再去枚举邻点这样,开一个 BIT 即可处理查询。

考虑分析复杂度,\(a\) 是 \(O(\sqrt q)\) 的,而 \(a\) 的总和不超过度数和,是 \(O(q)\) 的,每个点降级的时候枚举邻边,因此枚举量是 \(O(q\sqrt q)\) 的,总降级次数又是 \(O(q)\) 因此 BIT 部分复杂度 \(O(q\log n)\),于是通过本题。

[MXBZ2026 R17] 树跨度 / #12118. Dendrology

正确 dsu on tree 做法见这里,这里讲一下我赛时的奶龙做法。

正确思路第一步应该对每条边统计覆盖它的个数,但主播没想到,考虑对每个点统计,显然也是只要至少两个子树有即可。我们对 \(r\) 扫描线,那么每个点必然贡献一个前缀的 \(l\),更进一步,你发现每个点的贡献要么不变,要么变为 \(r-1\),更进一步,变为 \(r-1\) 的必然为 \(r-1\) 对应点和 \(r\) 对应点路径上的点,就可以树剖做。

但是修改就很不友好了,你考虑一次修改互换两条边,你发现同时包含两个点的和同时包含这条边两侧点的区间均不受影响,只需关心其他点都在一侧且包含了端点之一的区间,做一做发现需要支持区间 lower_bound 状物,我们对序列分块,然后对每个块再搞一个值域分块,于是就做完了。复杂度 \(O(n\log^2 n+n\sqrt n)\)。没调过,应该没问题吧。

[MXBZ2026 R17] 异或染色 / #17149. XOR Раскраска

从高到低在 01-trie 上分治,将 \(A\) 中元素按当前位分为 \(A_0,A_1\),\(B\) 中元素同理分为 \(B_0,B_1\),为方便 \(x\gets x+1\) 转 \(<\),分讨 \(x\) 的当前位:

  • 到底了,全部相等,因为转了 \(<\) 因此是不冲突的,如果没有可以全部并入的颜色就新开一个,否则无需额外颜色。
  • \(0\),则 \(A_0,A_1\) 的集合必然无交,我们递归处理 \((A_0,B_0)\) 和 \((A_1,B_1)\) 取二者所需的 \(\max\) 即可。
  • \(1\),则对于 \((A_0,B_0),(A_1,B_1)\) 其内部 \(S\) 拉满了,不过 \((A_0,B_1),(A_1,B_0)\) 仍需考虑。
    • 若 \(B_0,B_1\) 有一个为空,不妨设为 \(B_0\),那么 \(A_1\) 需要 \(|A_1|\) 个颜色,\(A_0\) 中的要么与 \(B_1\) 全无交可以任意加入 \(A_1\) 集合,否则全不可以加入 \(A_1\) 集合,我们递归入 \((A_0,B_1)\) 算即可,递归的时候传一下是否有可合并的集合的参数这样对于 \(|B|=0\) 的就可以判定是否需要新开一个颜色。
    • 否则二者均非空,则 \(A_0,A_1\) 内部元素颜色均不同,同时若 \(A_0\) 中某元素与 \(B_1\) 中某元素异或起来小于 \(x\) 则与其他所有元素异色,\(A_1,B_0\) 同理,剩下的元素对没有限制,于是我们统计一下未钦定与所有元素不同的元素个数即可计算,也就是给定一个 \((A,B)\) 求 \(A\) 中与 \(B\) 中所有元素异或均 \(\ge x\) 的元素数量,可以类似递归计算。

10.31

P17831 [CSP-S 2026] 能量水晶 / crystal

升序排序然后双指针即可。

P17832 [CSP-S 2026] 地铁 / subway

\(O(md^2)\) 地预处理出所有换乘方案的代价,然后跑一个 \(O(n^3)\) Floyd 最短路,询问 \(O(qd^2)\) 枚举每个询问的两个站点初始选择线路然后直接求距离即可。

P17833 [CSP-S 2026] 迁徙 / migrate

来点小分讨 DP。

首先肯定预处理出每个点往右能跳到的最远位置 \(to_i\)。恰好两种方案的话,模一下会发现必然形如某一步跳了最远的位置和次远的位置形成了分叉,然后后面又回到一起。

但这个过程还是很复杂。一个关键观察是,从 \(i\) 跳一步分别跳到 \(to_i,to_i-1\) 后,若 \(to_{to_i-1}<to_{to_i}-1\),那它显然是被 \(to_{to_i}-1\) 完全压制的,也就是 \(to_{to_i-1}\) 能以最小步数跳到的位置 \(to_{to_i}-1\) 都可以。因此,对每个点,都只需考虑它之前至多两个邻点就可以了,往后跳能直接转移到新的状态,考虑 DP。

首先设计 \(f_i\) 表示考虑到 \(i\),前面可以以同样步数跳到 \(i,i-1,i-2\),满足从 \(i,i-1\) 均可以最短步数跳到而 \(i-2\) 无法以最短步数跳到的终点数。

首先考虑一步能跳到的终点:

  • 若 \(i-2\) 存在且 \(to_{i-2}>i\),则算上 \(to_{i-1}-to_{i-2}\) 这些位置。
  • 否则,算上 \(\max(i,to_{i-1})-i\) 这些位置。

然后考虑再往后跳,分讨四种情况(靠后的情况默认前面的情况不被满足的前提):

  • \(to_{i-2}=to_i\),三个点都一步跳到同一个点,方案数必然不可能为 \(2\) 了,没有额外贡献。
  • \(to_{i-1}=to_i\),两个点必然跳到一块去,要求后面方案唯一,我们设计 \(g_i\) 表示 \(i\) 可以以最短步数跳到而 \(i-1\) 不行且方案唯一的终点数,则有 \(g_{to_i}\) 的贡献。
  • \(to_{i-1}=to_i-1\),注意到 \(i,i-1\) 都能跳到 \(to_i-1\)(\(to_{i-1}=i\) 的情况有点特殊,但是可以发现不影响转移正确性故不用额外考虑),因此后面要求 \(to_i-1\) 不能跳到且方案为二,我们设计 \(h_i\) 表示 \(i\) 可以以最短步数跳到而 \(i-1\) 不行且方案恰为二的终点数,则有 \(h_{to_i}\) 的贡献。
  • \(to_{i-1}<to_i-1\),没啥好说的有 \(f_{to_i}\) 的贡献。

考虑 \(g,h\) 的转移,类似上面分析可得:

\[g_i\gets to_i-\max(to_{i-1},i)+[to_{i-1}<to_i]g_{to_i}\\ h_i\gets\begin{cases} 0 &,to_{i-1}=to_i\\ h_{to_i}&,to_{i-1}=to_i-1\\ f_{to_i}&,to_{i-1}<to_i-1 \end{cases} \]

特别地,对于 \(to_i=i\) 的点,有 \(f_i=g_i=h_i=0\)。

答案的话枚举起点即可,即为:

\[\sum_i f_{to_i} \]

P17834 [CSP-S 2026] 研发基地 / hub

二分答案 \(m\),一个比较典的 trick 是去剥叶子,记剥 \(m\) 轮后留下的点集为 \(S\),若 \(|S|\le k\) 显然合法,否则要删去 \(|S|-k\) 个点。

因为至多得到两个连通块,同时 \(S\) 内所有叶子必须被包含,相当于在某一条二度链上删去连续一段,对链上每个点预处理出其链外最大深度,则他相当于给删去段的起点了一个非法区间,做个差分看是否有起点未被覆盖过即可。

posted @ 2026-09-01 14:07  LastKismet  阅读(158)  评论(3)    收藏  举报