记录(3)
半平面莫队构造
做法1
做法2
炉心融解
做法1
对于每一回合,有两种类型的信息:
1.公共的信息:主持人公布的信息、哪些人根据之前的信息作出推断。
2.每个人独有的信息:除自己相邻两个人之外的其他人的状态。
设 \(dp_S\) 表示在当前回合,若假定所有人的状态为 \(S\),是否违背所有之前的公共信息。
利用当前回合的 \(dp\) 值,可以得到对于每个人,在当前回合是否能够报告。
在回合结束时利用新增的公共信息,筛去不合法的状态 \(S\)。
时间复杂度 \(O(2^n(2000+nm))\)
做法2
设 \(f_{S,i,T}\) 表示当前回合,假设状态为 \(S\),第 \(i\) 个人,周围的两个人的状态是否可以是 \(T\)。
时间复杂度有点爆(当然可以设一些中间状态强行优化)。
做法1是从上帝的角度设计 dp,做法2是具体到每个人的视野设计的 dp。
Hat Puzzle
还是维护一个维护所有可能的状态的集合。对于一个状态,我们将其看成一条从 \((0,0)\) 到 \((n,c)\) 的路径。
那么一轮对于一个人,需要从集合中排除掉所有能否唯一确定这个人的帽子颜色(也就是第 \(i\) 步的走法)和给定的状态 \(S\) 不同的状态 \(T\)。假定状态是 \(T\),可以确定 \(i\) 的帽子颜色等价于先顺着 \(T\) 走完前 \(i-1\) 步,再从可行状态集合中拼上后半段,在第 \(i\) 步的走法是唯一的。枚举 \(T\) 经过了 \((i-1,a)\),那么所有经过 \((i-1,a)\) 的 \(T\) 都没有区别,所以 ban 掉所有经过 \((i-1,a)\) 的 \(T\) 相当于 ban 掉 \((i-1,a)\)。
如果可以确定,一定能在 \(n\) 轮之内确定。所以只需模拟 \(n\) 轮。
5月14日模拟赛
T1
二维 dp 变一维
转置原理
T2
延迟钦定,如果一条链的末端是虚点,且下一个点也是虚点,就继续接上末端向下的链,形成一个整链,当一个链成型变成整链的时候再计算内部的方案数,即 \(c!\)。
合并点 \(u\) 的分支时,有三种情况:
- 儿子内部发生匹配,形成跨过 \(u\) 的弯链
- 没有跨过 \(u\) 的弯链,\(u\) 所在的链向下延伸到了一个儿子 \(v\)
- 没有跨过 \(u\) 的弯链,\(u\) 所在的链在 \(u\) 就断了
合并一个点的儿子 \(dp\) 值,\(dp_{0/1/2}\) 分别表示 \(u\) 向下延伸的链个数为 \(0/1/2\)。
T3
1.\(x\ge y\)
2.\(x<y\)
分讨 \(a_1,a_2\):
1.如果 \(a_1\le a_2\),将 \(a_1\) 都连到 \(a_2\) 上
2.如果 \(a_1\ge a_2+2\),\(a_1-=2\)
3.如果 \(a_1=a_2+1\),有两种可能:\(a_1\) 落单一个,或 \(a_1\) 内部连一对,剩下的都连到 \(a_2\) 上。
\(dp(i,x)\) 表示 \(a_i=x\)。进行归纳,任意 \(i\) 只有 \(x,x+1\) 两个有值的位置。
建图,\(dp(i,0/1)\) 到 \(dp(i+1,0/1)\) 有一条边,边权是一个二维向量。要求 \(dp(1,0)\) 到 \(dp(n+1,0)\) 的所有路径构成的凸包(注意并不一定关于 \(x\) 凸,但可以只留点集的凸包) 分治,返回 \((l,0/1)\to (r,0/1)\) 的凸包,合并时做闵和,求出新的点集,再新求一遍凸包。
New Balls
做法1
如果两棵树可以通过 edge replace 分别 \(n-1\) 次,得到同一棵树,那么这两棵树就是永远无法区分的。因为 edge replace 可逆,因此等价于一棵树通过 \(2n-2\) 次 edge replace 变为另一棵。一棵树变为另一棵树的最少操作次数等于不同的边数。即构造 \(n\) 棵树,任意两棵树边集不交。
将 \(2n\) 个点的完全图划分为 \(n\) 棵树/\(n\) 个哈密顿链的其中一种做法:将 \(2n\) 个点排到一个圆上,Z 字型覆盖。
做法2
有 \(2n-1\) 条边,而最多改变 \(n-1\) 条边的信息,因此考虑让每条边传递相同的信息,取众数。
让一条边传递的信息是两个端点编号模 \(n\) 之和。构造 \(n\) 个树,让这个信息分别是 \((1,2),(3,4),...\)。先构造出 \((1,2)\):蛇形 \(1,N,2,N-1,...\) ,接着将每个点编号同时 +1,就能依次得到剩下的 \(n\) 种。
将所有图叠在一起,就是做法1了。
Telepathy
Minesweeper
做法1
利用平面图的性质:\(e\le 3v-2\)。所以总是存在一个点度数不超过 \(5\),不断将这个点剥去,得到一个拓扑序。根据拓扑序去依次确定每个点是不是雷。对于第一个雷,后面相连的最多 \(5\) 个雷(受度数限制),给它标上 \(6\)。第二个雷标 \(7\)。后 \(5\) 个雷额外传过去。
做法2(加强版——非平面图、仅两个点无法确定)
还是从 \(1...n\) 依次确定,假设到一个点的时候前面的雷都是已知的。
考虑一个雷,假设它不是雷,那么上面的数字一定在 \([c,c+k-i]\) 一个长度为 \(k-i+1\) 的区间内(前面 \(i\) 个雷,前面已知相连的有 \(c\) 个)。那么只需要赋一个 \(p_i\) 不在这个区间内即可。
每个雷的窗口长度依次是 \(k+1,k,...,2\)。先把 \(k+1,k\) 给确定了。对于 \(k-1\),\(k\) 个数,一定有一个数不在 \(k-1\) 个 ban 掉的数之中,对于 \(k-2...\) 同理。
这个做法进一步利用到了每个雷的范围是一个从 \(k+1\) 到 \(2\) 依次递减的窗口,再利用抽屉原理填入排列。
Guess the Permutation
什么一定做不了:一定不可能用少于 \(n/2\) 次操作就声称自己找到了 \(1\),不然小心交互库全部 \(*2\)。
考虑询问两个数 \(a,b\),假设 \(a<b\),得到 \(c\),那么 \(p_b=p_a+p_c\)。也就是将 \(p_b\) 表示为两个数之和,只需要得到 \(p_a,p_c\),按照拓扑序从大到小就能得到 \(p_b\)。一次询问几乎总是可以得到足够的信息,除非 \(a>b\)。
假定 \(a<b\),然后做辗转相减,不断让 \(b\) 减去 \(a\),如果减了两次后发现回到了原位,就撤回原先的假设,并交换 \(a,b\);如果遇到之前已经访问过的数,就退出,重新找一个 \(b\) 继续辗转.
感性理解,每多浪费的两次步数,都会用以交换 \(a,b\).总次数应该不会超过 \(n+2\log_2 n+O(1)\).
Telepathy
做法1(折线图)
在这个集合视为 -1,不在视为 1,做前缀和.因为 \(k<n/2\),所以最后一定在 \(x\) 轴严格上方.
考虑令 Bob 的策略为选择折线图最低点,如果有多个,选择最靠前的一个.
那么 Alice 可以将一个向上变为向下,找到最低点,将它后面变为向下,因为最后落在 \(x\) 轴上方,所以它一定不是最末尾.并且这样给 Bob 的最低点也是唯一的.
做法2(括号匹配)
在这个集合视为 (,不在为 ),做括号匹配,那么剩余的括号形如 )))((((,并且一定有 ) .
Alice 的策略为选择最后一个 ) 改为 (,Bob 的策略为找出第一个 (.
你的生命已如风中残烛(Raney 引理)
令 \(b_i=a_i-1\),那么要求:
\(b_1\ge 0\)
\(b_1+b_2\ge 0\)
...
\(b_1+b_2+...+b_m\ge 0\),事实上,\(b_1+b_2+...+b_m=0\)。
构造 \(b_{m+1}=-1\)。则对于一个和为 \(-1\) 的序列,其 \(m+1\) 个循环移位中,恰有一个满足除整个序列外的所有前缀和非负,即:
\(b_1\ge 0\)
\(b_1+b_2\ge 0\)
...
\(b_1+b_2+...+b_m\ge 0\)
\(b_1+b_2+...+b_m+b_{m+1}=-1\)
并且 \(b_{m+1}\) 一定等于 \(-1\)。所以对于 \((m+1)!\) 个元素(互不区分)的排列根据循环移位划分为 \(m!\) 个等价类,每个等价类恰有一个满足条件。因为最后附加的一个 -1 和其他 -1 不可区分,因此还要除掉 \(m+1-n\)。方案数为 \(\frac{m!}{m+1-n}\)。
raney 引理完整版:
如果 \(x_1,x_2,...,x_m\) 是任何一个和为 \(1\) 的数列,则其所有循环位移中恰好有一个满足所有的前缀和(非空)都是 \(>0\)。
如果 \(x_1,x_2,...,x_m\) 是任何一个和 \(<0\) 的数列,则其所有循环位移中恰好有一个满足所有的前缀和(非整个序列)都是非负。
DFS Order 6
最大值:DFS 树,所有边都是反祖边。
最小值:BFS 树,所有边都不是反祖边。
那么猜测之间的都可以被构造。要构造一个结合 DFS 树和 BFS 树的折中的方案。
DFS 的过程,
Sticks 2
类似内存对齐?
世末歌者
先把每个数一直转到没有人的位置。这样假设每个人在环上的位置两两不同。
再转一下 \(1\),依次对每个人转一圈定位到相对 \(1\) 的坐标。最后根据坐标转到正确的位置。
根据不同的优化方向衍生出两种做法。
做法1
做法2
并不需要假设所有人的位置是个排列。只需要保证状态的串没有循环节。而这个可以通过改变 \(1\) 的位置达到。
如果一个串是循环串,改变任意一个字符之后一定不是循环串。证明,设 \(a\notin S\):
\(a\in T,a+v\in T,a+v\in S,a+v+u\in S,a+v+u\in T,a+u\in T,a+u\in S,a\in S\)。
DFS Order 6
不断尝试对每个起点进行检查,将能推断一定不可能存在的边删掉,对相关的结点继续检查。如果中途没有寄掉的前提下,无法继续删边,说明每个起点都合法,那么也就找到了一组合法的解。
Alternative Accounts 2
一次交换 \(x,x-1\) 实际上给我们带来了哪些信息?有且仅有:\(p_x\) 和它后面的 \(p_y\) 不可能配对。
给能配对的点对之间连边,那么就是求完美匹配个数。
发现对于三个点 \(\bm{a,b,c}\),如果有边 \((a,b),(b,c)\),\((a,c)\) 大概率也存在。(假如一定存在,就变成若干个团了不是吗,考虑任意两个联通的点一定存在一条路径,进而存在一条边。)
具体的,设 \(a<b<c\),\((a,b),(b,c)\) 能推到出 \((a,c)\);\((a,c),(b,c)\) 能推导出 \((a,b)\)。证明:大力分讨,只考虑 \(a,b,c\) 的相对顺序,考虑谁先把谁交换掉,以此来分讨。
考虑一个点向编号比它小的连出去的边,只保留编号较小的边。那么一个点实际上的边是这棵森林上的祖先。证明:分 \(l_y<z\) \(l_y>z\) 分别讨论,前者 \((l_y,x)\) 一定存在,后者 \((y,z)\) 一定存在。
建出树来做 dp。从上向下不好做,所以从下往上记录子树内有几个点没被匹配。
观星者
无环说明是森林。添加 \(p_i<p_j\) 的边后,不改变联通性。
森林的结构具有很好的递归性,不妨假设根是 \(1\),那么 \(1\) 连出去的若干条边会划分成若干个子树,子树之间两两无边。找到所有前缀最小值的位置,这些位置都会连到 \(1\),并且这些段满足 \(p_1=1\);除此之外,对于最后一个子树比较特殊,因为连向 \(1\) 的代表元不一定是在开头,也不一定要是前缀最小值之一,因为前面可以有 \(<p_1\)。更具体地,这个位置一定是前缀最大值,并且高度为 \(p_1\) 的水平线恰好切在了这个点的下方。
如图。

设 \(dp_{l,r,0/1,s}\) 表示 \([l,r]\),是否要求 \(p_1=1\),前缀最大值的下标集合为 \(s\)。枚举 \(l\),扫描 \(r\) 做转移。\(0\) 可以看成是 \(1\) 后面接了额外的一段,枚举特殊段段长转移。\(1\) 的话,就枚举最后一段的段长,从另一个 1 转移过来。\(s\) 要取划分的第一段的 \(s\)。
Sticks 2
经典贪心的道理:从高到低,如果能选不选,说明后面一定存在一个子集恰好是 \(2^i\),可以直接替换。
5月19日模拟赛
A
分讨 border 长度 \(x\):
(较小)\(x\le a\)
(居中)\(a<x\le b\)
(较长)\(b<x\),周期 \(a+b-x<a\)。
较短分析 border,较长分析周期。
B
Git Gud
思想类似单点加、前缀求和的三次分块:总是可以通过叠加分块的层数使得复杂度接近 \(O(kn^{1/k})-O(k)\).
这个题,先写出一个分块的做法,次数为 \(2(n+1000n^{1/2})\),发现这里 \(1000n^{1/2}\) 占了大头,比前面的 \(n\) 大了不少。
若使用三次分块,次数为 \(3(n+1000n^{1/3})\)。
Circle of Cows
首先有结论:连接圆上匹配的两个点,任意两条弦都交叉。
先二分答案之后,仍然不好直接贪心,所以再枚举第一条弦。那么其他的弦都和第一条弦交叉,所以是一个二分图,其中一侧的点能匹配到的是一段弧,并且只会单调移动,所以直接贪心匹配。
把二分扔了,直接枚举最段的弦。复杂度 \(O(n^3)\)。
All Pairs Shortest Paths
这个神秘的网格是正三角形网格和两个错开的正六边形网格的叠加。所以把经过的边拆到三个网格之上,独立计算。
正三角形网格和正六边形网格是类似的,还是分经过的边的方向横竖斜独立计算。
然后有点小问题,如果两个点在某一条斜线上(三种斜线),需要微调一下,多算个 \(1\)。
Two Characters, Two Colors
做法1
最大化收益,考虑最小化支出。
最小割切糕模型,可以连出来一个只有中间一层的图,前面的 \(1\) 向后面的 \(0\) 连有 \(1\) 的容量。
最小割转最大流。然后是模拟最大流?!
先把经过每个点上下两条边先流了,之后看 \(1\) 流入是否有多余,\(0\) 流出是否有剩余,维护一个可重集,在 \(1\) 的时候加入,在 \(0\) 的时候将前 \(k\) 大减去 \(1\),使用平衡树维护。注意了无数遍了:fhq treap 是 leafy 的,向上 pushup 的时候不要忘了自己的值,和向下 maketag 的时候别忘了把 tag 复合到自己身上。
Crossing the Railways
先做一些变换:将 \(y-=vx\),要求直线斜率 \(\ge 0\).
调整:找到一条直线,沿着上一个拐点的位置往前走,走到一个连线触碰关键点的位置为止,或是走到头了(这种答案直接少了 \(1\)).再顺时针旋转,直到转到另一个关键点,或者斜率变为 \(0\).所以只有经过两个关键点,或者斜率为 0 的直线是有用的.(斜率为 0 好像也不必需?)这样的直线只有 \(O(n^2)\) 条.
有了直线,考虑直线之间如何拼接.设 \(dp_{i,j}\) 表示到第 \(i\) 列,在第 \(j\) 条直线上.转移需要考虑在 \(i\to i+1\) 处的直线切换.切换的两条直线在 \(x=i\) 和 \(x=i+1\) 的高度顺序一定相反,也就是一个逆序对,使用树状树组维护.还有可能在一条较低的线等待,再走到另一条较高的线上,这种代价是 \(2\)(因为由有速度->静止->有速度).
卡常:相同次数的(5e6)次 unordered_map 操作比排序+两次BIT 总和满了两倍.map 比 unordered_map 还慢.在 CF 评测机上尤其慢.
The Third Grace
做法1
枚举 \(j\),从维护从 \(i\) 转移到 \(j\) 的贡献,那么就是:区间 \(a_i+=p_i\);查询全局 \(a_i\) 最大值.使用 KTT 维护"一次函数" 和统治的时间.时间复杂度 \(O(n\log^3 n)\).
做法2
枚举 \(i\),主动转移到所有的 \(j\).维护 \(x_j\),支持区间 \(x_j\) 加减 1(操作后仍然保持单调性),全局 \(ans=\max(ans,kx_j+b)\).使用李超树维护,将挂的直线看作"懒标记",区间平移时将不完全包含的懒标记下放,因为有 \(O(\log n)\) 个结点,下放 \(O(\log n)\),时间复杂度 \(O(n\log ^2)\).
这个做法多利用了单调性.
P3599
第二问
\(n\) 一定放在最后.\(s_{n-1}=\prod_{i=1}^{n-1}i\),则 \(s_{n-1}\ne 0\),可得 \(n=1,n=4\) 或 \(n\) 是某个质数.
一种办法是构造 \(\frac{i+1}i\),也可以取某个原根 \(g\) 转化为第一问.
Alexey the Sage of the Six Paths
最小点覆盖和最大匹配的联系:

\(T_1\) 中的点向左都和 \(S_1\) 中的某个点匹配,\(S_0\) 中的点向右都和 \(T_0\) 中的某个点匹配,没有 \(S_1,T_0\) 的边。
那么我们说:这个图最大匹配等于最小点覆盖等于 \(|S_0|+|T_1|\)。
如何通过残量网络构造这样的结构(其实也就是给定最大匹配构造最小点覆盖):在残量网络上 bfs,bfs 到的左、右部点分别叫做 \(S_1,T_1\),没被 bfs 到的分别叫做 \(S_0,T_0\)。
平面魔方
正式比赛遇到构造题一定分配充足的时间。即便自己认为自己会了也不代表真的会了,会有很多 corner case 不会整个题也是不会,甚至不一定能得到部分分。所以一定多加小心。
手玩出了某种构造一定另外拿一张纸记录下来。别到时候又忘了。
Roadworks
性质很多。发掘单调性。
对于每个房子,求出能到它的最早的时刻 \(t_i\)。那么 \(s\) 左右 \(t_i\) 分别是严格的单调的。
路径应该是先到一个房子停留,再中间不停留到另外一个房子,继续下去,过程中有可能换边。
中途停留的房子按照经过顺序一定满足 \(t_i\) 是单调的。
对于一个房子,如果要在这个房子停留,一定是停留最长的时间,再恰好走到下一个要停留的房子。否则可以将路径整体向上平移。
也就是,将 \((i,t_i)\) 设成关键点。可以用李超树/凸包优化 DP。
中途停留的房子按照经过顺序一定满足 \(h_i\) 是单调的。
如果从 \(i\) 到右边的 \(j\),中间存在一个 \(k,i<k<j\),满足 \(h_k>h_j\),那么不如先到 \(k\),再到 \(j\)。如果 \(i\) 到左边的 \(j\) 也是同理。所以只有 \(h\) 前后前缀最大值是有用的。每个点的转移边只有两条,因为已经筛出了前缀最大值,可以用双指针。复杂度线性。
Wowee Binary String
假设留下来的位置分别是 \(p_1...p_m\),那么相当于对于 \(p_i,p_{i+1}\) 之间要么有 ?,要么和是偶数。
一个点的转移边不唯一,在非确定性自动机上 DP 需要记录一个集合。但是发现对于两个匹配点,只有当之间既没有 ? 也满足和是偶数的时候后面才有可能优。
先把非确定性自动机转成 \(2^{|S|}\) 大小的确定性自动机,再将确定性自动机的点数减少到 \(N^2\)。
The Endians
混沌邪恶:菊花的时候是凸的,链的时候是凹的(二次函数)。解集也没有什么包含的性质。\(k\) 是定的导致也不能保留凸壳。
换根,相当于 \(u\) 加上其他子树转移到某个儿子 \(v\)。对于 DP 数组只用保留 \(size_v\) 的信息。
方便的写法:三度化
Haybale Stacks
可以把背包的过程看作是在一个数轴上跳,步长不超过 \(100\)。对于 \([p_i,p_i+100]\) 之内的数设为关键点。需要处理关键点到关键点的转移。
- 非关键点到上一个关键点:对于每个奶牛,是否有用是确定的,这是一个经典问题,考虑性价比最高的奶牛,余项再做一个 \(100\times 100\) 的背包。
- 关键点到关键点:枚举选择哪个奶牛,再利用 1. 转移。预处理 \([p_i-100,p_i]\) 之间的答案。
然后处理对于询问,先跳到后面第一个关键点,再利用 1. 计算。
Perfect Binary Trees
满二叉树的形态只有 \(\log n\) 种,而满二叉树在一个子树内的形态只有 \(2\log n\) 种(子树和子树补),再加上一个子树内已经成型的状态,一共记录 \(2\log_2 n+1\) 种状态 DP。
popcount ≥ K
连加 \(N\) 次 \(C\) 的过程中,最高的进位是比较重要的,所以枚举 \(t\),表示第 \(t\) 位从 \(0\) 变成了 \(1\)。对于前面的位,如果要贡献 \(prefix\),肯定是连续 \(prefix\) 个 \(1\)。枚举 \(prefix\)。再枚举进位之后是 \(2^t+r\),其中 \(0\le r<C\)。把 \(2^t\) 以内所有 \(\bmod C=r\) 的数拿出来,求前缀/后缀连续的 \(popcount≥ K-prefix\) 的个数。设 \(f(t,r,K,C)\) 表示 \(2^t\) 以内 \(\bmod C=r\) 的信息。根据第 \(t-1\) 位是 \(0/1\) 转移到 \(f(t-1,r,K,C)+f(t-1,r-2^{t-1},K-1,C)\)。
5月26日模拟赛
T3
sub2做法1
找到任意一个点权非负的点,将它和父亲合并。但是这里根不一定要选,假设选的连通块根是 \(x\),那么实际上答案是同连通块内 \(x\) 子树的边权之和。用树剖维护子树和,并查集合并。
另一种理解:DP。\(\max_{dp_v+w,0}\) 是取到了前面还是后面,对于取到了前面的边,叫做实边,把虚边断掉,形成若干个连通块。
sub2做法2
长剖。
静态 Toptree
重子树分治合并,轻子树合并果子哈夫曼树/分治合并。Rake Compress 实质上是合并轻重儿子。一个簇由上下两个界点确定。toptree只能维护边的信息。记录上下界点状态。o[2][2]
注意rake compress 的顺序。注意toptree二叉树的两个儿子是有序的。
静态并不是指没有修改,而是说树的结构不会发生变化。
类似线段树用于解决序列上范围修改查询,toptree 可以用来解决树上范围修改查询。还真是??所有我学过的树上的范围修改数据结构(树剖?LCT?)都可以看成是 toptree 的一种变体。
各种范围在 topcluster 上的表示:
topcluster:一个 Cluster 最多有两个界点,两个界点存在祖先关系,非界点不会暴露在外。
子树:
摄神取念
考虑如何问出相邻两个数的大小关系。对于每个 \(i\),找到最大的 \(j\),使得 \(a_i\) 被 \([j,i]\) 的包围盒包含。那么 \(j\) 和 \(j-1\) 的大小关系和 \(i\) 和 \(i-1\) 的大小关系相反。
只有上下凸壳上的点是有用的,并且一定可以只有上下交替横跳的位置是有用的。
[湖北省选模拟 2025] 团队协作 / team
先考虑如何计算所有独立集的最大值之和. 枚举最大值,使用 toptree 维护,记录 o[2][2] 表示上/下界点的状态.
转置原理.扫描最大值 \(X\),将 \(\le X\) 的点激活,再使用 toptree 维护.同时维护懒标记 tag[2][2] 表示要给参与组成 o[2][2] 的点的答案下传多少.相当于把 o[u]+=o[ls]o[rs] 转置成 tag[ls]+=o[u]o[rs],tag[rs]+=o[u]*o[ls]. 易错:最后把 tag[2][2] 传给 ans[u],这一步转置也不要忘记.
5月28日模拟赛
T1
枚举结束时手上的数,那么可以确定最后的序列 \(b_1,...,b_n\)。如果 \(a_i\ne b_i\),连一条 \(a_i\to b_i\) 的边,表示这一对数需要交换。交换的过程可以看作是在和图上走出一条欧拉路径。
如果有 \(c\) 个连通块,需要加入 \(c-1\) 条边使图联通。所以交换次数至少是(边数+非孤点连通块个数-开始时手上的数不是孤点)。
类似:Incomplete Shuffle
充要条件:置换环是一个大环。可以通过归纳证明。
连边 \(A[i]\to B[i]\),可以从 \(A\) 变成 \(B\) 等价于存在欧拉回路。
那么问题是改最少的边的出点(或者说入点,对称的,不影响答案),使得存在欧拉回路。
判掉答案为 \(N\)。问题可以改写为,选择最多的路径,再将路径首尾相接。对每个连通块,至少需要一条路径。对于每个点,至少需要新开 \(\max(out_i-in_i,0)\) 个路径。这个下界且可以很简单的取到。
Festivals in JOI Kingdom 3
具体细节如下。
对每个点:维护轻儿子信息并;
对每条重链:维护“走一条边-合并一个点的轻儿子”的信息,信息支持合并(复合)。
\(calcdp(u)\):计算 \(u\) 子树的 dp 值,从重链的底部(dp 值为 \(+\infty\))开始计算。
修改单点/边:先从上到下在父亲的轻儿子列表中撤销,中途不要在重儿子线段树更新 dp 值。再从下到上加入轻儿子列表,中途在重儿子线段树上不断更新 dp 值。
\(dellight(u)\),\(addlight(u)\):将 \(u\) 加入到父亲的轻儿子列表中/从中删除。
\(updlight(v)\):将 \(v\) 的轻儿子信息加入重链线段树。
若要支持换根:从上到下,交替“走一段重链,走一条轻边”,最后多走一段重链。

浙公网安备 33010602011771号