杂题选做Ⅳ


NOIp 前夜了,可我还是发现自己有一车 blog 没补,所以只好开一个新坑/wul

前传:

76. CF1539E Game with Cards

考虑设 \(dp_{i,0/1}\) 表示目前已经进行了前 \(i\) 次操作,第 \(i\) 次操作替换了左手/右手是否可行,以 \(dp_{i,0}\) 为例,转移就枚举上一次使用右手是拿一次操作,不妨称之为 \(j\),那么有转移 \(dp_{i,0}\leftarrow dp_{j,1}\land[a_{l,j+1}\le k_{j+1}\le b_{l,j+1}]\land[a_{l,j+2}\le k_{j+2}\le b_{l,j+2}]\land\cdots\land[a_{l,i-1}\le k_{i-1}\le b_{l,i-1}]\land[a_{r,j+1}\le k_j\le b_{r,j+1}]\land\cdots\land[a_{r,i-1}\le k_j\le b_{r,i-1}]\)。直接做是三方的,显然不可取,因此考虑预处理一些东西。

我们预处理出 \(nxt_{i,0}\) 表示最大的 \(r\),满足 \(\forall j\in[i+1,r]\) 都有 \(a_{l,j}\le k_i\le b_{l,j}\),同理设 \(nxt_{i,1}\) 表示最大的 \(r\),满足 \(\forall j\in[i+1,r]\) 都有 \(a_{r,j}\le k_i\le b_{r,j}\)

我们再设 \(pre_{i,0}\)​ 表示最小的 \(l\)​,满足 \(\forall j\in[l,i]\)​ 都有 \(a_{l,j}\le k_j\le b_{l,j}\)​,以及 \(pre_{i,1}\)​ 表示最小的 \(l\)​,满足 \(\forall j\in[l,i]\)​ 都有 \(a_{r,j}\le k_j\le b_{r,j}\)

那么 \(dp_{j,1}\) 可以转移到 \(dp_{i,0}\) 的充要条件是 \(dp_{j,1}=1\),且 \(nxt_{j,1}\ge i,pre_{i,0}\ge j\)。因此我们考虑建两棵树状数组 \(T_0,T_1\),对于一个 \(dp_{i,0}=1\)\(i\),我们就令 \(T_0\)\(nxt_{i,0}\) 的上位置对 \(i\)\(\max\)​,对 \(dp_{i,1}\) 也进行同样的操作,那么 \(dp_{i,0}=1\),等价于树状数组 \(T_1\)\([i,n]\) 的后缀 \(\max\) \(\ge i\)​,\(dp_{i,1}=1\) 的条件也是类似的,这个在树状数组查一遍后缀 \(\max\) 即可转移。

至于输出路径,就随便记录一个 \(pre_{i,0/1}\) 表示 \(dp_{i,0/1}\) 是从哪儿转移来的,然后最后不停地跳 pre 即可。

时间复杂度 \(\Theta(n\log n)\)

77. AT2667 [AGC017D] Game on Tree

打 CF GR 时发现 I 题题面里有一道我没做过的 AGC 就在弃赛以后来做了(

首先先抛结论:考虑 SG 定理,那么每个子树的 SG 值等于其所有儿子的子树的 SG 值加 \(1\) 的异或和。

为什么呢?考虑每次删除一个子树 \(x\) 内的边的过程是怎么样的,我们假设 \(x\)\(t\) 个儿子,那么我们将 \(x\) 复制 \(t\) 边,然后每个 \(x\) 下面都接上 \(x\) 的一个儿子的子树。那么显然这 \(t\) 棵树可以视作独立的游戏,直接将它们的 SG 值异或起来就是原游戏的 SG 值。那么又该如何算根节点只有一个儿子的游戏的异或值呢?可以证明,如果根节点只有一个儿子的情况,那么它的 SG 值就等于它唯一的儿子的子树的 SG 值加 \(1\),这个就考虑,如果我们割掉了 \(x\) 与这个儿子之间的边,那么只剩下一个节点,SG 值显然为 \(0\),而如果第一次割掉的边不是 \(x\) 与其儿子的边,那么我们归纳一下可以得到剩下部分的 SG 值就等于去掉根节点后剩余部分的 SG 值加一。换句话说,对于割掉 \(x\) 的儿子的子树内的边可以得到的 SG 值 \(x\)\(x+1\) 同样可以被得到,反之对于对于割掉 \(x\) 的儿子的子树内的边后不可以得到的 SG 值 \(x(x\ge 0)\)\(x+1\) 同样不可以得到,这样 \(x\) 的子树的 SG 值就显然等于其儿子的 SG 加一。

78. CF1610I Mashtali vs AtCoder

关于上题中提到的 GLBR 的 I 题,它来了(

首先套用上一题的结论解决 \(k=1\) 的情况:一棵子树的 SG 值等于其儿子的 SG 值 \(+1\) 的异或和。

对于 \(k>1\) 的情况,有这样的结论:我们将编号为 \(1,2,3,\cdots,k\) 的点拎出来建一棵虚树并缩成一个点,不妨令这个点为根节点,然后将所有在缩点后,一个端点在缩成的连通块,另一个端点不在的边全部接到根节点上,那么 \(k\) 时的 SG 值,就等于以缩点之后的点为根计算出它们的 SG 值后,根节点的 SG 值,异或上 \(1\sim k\) 的虚树中的边数 \(\bmod 2\),只不过在计算根节点的 SG 值时,直接将根节点的儿子的 SG 值异或起来即可,不用 \(+1\)

这里稍微胡半个证明:首先我们称连接两个都在虚树中的边的点为一类边,其余的边为二类边,那么我们将割掉的边分为一类边和二类边处理,如果我们割掉一条一类边,那么根据 SG 值的定义,这条边所在缩点之后根节点的子树的 SG 值肯定会发生变化,而如果我们割掉一条二类边,那么二类边的奇偶性就会变化,因此不论割掉什么边,游戏的 SG 值总会发生变化。

为什么说是半个证明呢?因为我不太会证为什么一种局面总可以到达 SG 值比它小的局面(

因此对于本题而言,我们可以直接向上面那样加入一个点时不断跳 father 并将路上经过的边标记为二类边,由于每条边最多被标记一次,因此总复杂度 \(\Theta(n)\)

79. CF1612F Armor and Weapons

首先关键性质:答案不超过 \(\dfrac{\max(n,m)}{\min(n,m)}+40\)

因此不妨假设 \(dp_{i,j}\) 表示目前武力值最高的盾的武力值为 \(i\),进行了 \(j\) 次操作,所能够得到武力值最大的武器,转移就分下一次买盾和买武器处理即可。

时间复杂度 \(40n\log n\),瓶颈在于判断一对 \((i,j)\) 是否在读入的 \(q\) 组二元组中出现过。

80. CF1338D Nested Rubber Bands

一道看似很无从下手的题。不过仔细分析一下还是挺有迹可循的(

首先碰到这样的问题我们肯定要考虑什么样的序列可能符合条件。分析一下能够得到,一种选择符合条件,当且仅当对于所有点 \(u\),都不存在三个邻居 \(x,y,z\),满足去掉 \(u\) 后三个点所在的连通块中,都除了 \(x/y/z\) 之外还选择了其他的点,这是因为假设 \(x\) 所在的连通块中选择了 \(a(a\ne x)\)\(y\) 所在的连通块中选择了 \(b(b\ne y)\)\(z\) 所在的连通块中选择了 \(c(c\ne z)\)。且方便起见假设 \(c\) 包含于 \(b\)\(b\) 包含于 \(a\),那么画出图来肯定是张这样的:

而我们希望 \(u\)\(x,z\) 相交而与 \(b\) 不相交,显然在上图中这无法办到。

直接用这个结论解题貌似有点难以下手,我们不妨对这个结论进行等价转换。可以发现一种等价的表述:对于每一种合法的方案,必然存在一条路径 \(u,v\),满足所有选择的点到这条路径距离 \(\le 1\),也就是说题目等价于选择一条路径 \(u,v\),并将所有到这条路径距离 \(\le 1\) 的点提取出来求出它们的最大独立集。直接做显然会 TLE,考虑 \(dp\) 的思想,设 \(dp_{i,0/1}\) 表示目前考虑到 \(i\)\(i\) 是链的一个端点并且 \(i\) 选了 / 没被选所能选择的最大的点数。考虑转移,假设我们目前 DFS 到点 \(x\),下面要加入 \(x\) 的一个儿子 \(y\),那么有转移:

\[res \leftarrow \max(res, \max\limits_{i\land j = 0} dp_{x, i} + dp_{y, j}) \]

\[dp_{x, 0} \leftarrow \max(dp_{x, 0}, \max(dp_{y, 0}, dp_{y, 1}) + deg_x - 2) \]

\[dp_{x,1} \leftarrow \max(dp_{x, 1}, dp_{y, 0} + 1) \]

直接转移即可。时间复杂度线性。

81. AT4518 [AGC032C] Three Circuits

不难发现,一个连通块是一个题目中所谓的“可以经过重复点的环”,当且仅当它存在欧拉回路,即它连通并且每个点的度都是偶数。

那么我们的任务就可以转化为,将连通块的边集分成三部分 \(A,B,C\),满足它们都有欧拉回路。一个显然的必要条件是每个点在原图中的度都是偶数,否则假设 \(x\) 在原图中的度是奇数,那么在 \(A,B,C\) 中,至少有一部分满足 \(x\) 的度是奇数,不合题意。但是每个点的度都是偶数的情况也不一定符合条件,譬如一个环的情况就无法拆成符合条件的三个子图,因此考虑进一步分类讨论:

  • 如果存在一个点 \(x\) 的度 \(\ge 6\),那么我们感性地理解一下,每次选择这个点的两条出边,然后顺着找出经过这两条出边的一个环,然后将这个环从这张图中删去,如果删去这个环之后图被分成了两个连通块,那么我们就将不包含 \(x\) 的部分与之前拆出来的那个环归到同一个边集中。如此操作两次,连带剩余的部分,刚好三个回路。

  • 如果所有点度都 \(\le 2\),那么原图是一个环,显然无法完成任务。

  • 如果度数最大的点的度数恰好等于 \(4\),这部分有点繁琐,我们进一步分类讨论:

    • 如果度数为 \(4\) 的点只有一个,那么任务也没法完成,输出 No

    • 如果度数为 \(4\) 的点的个数 \(\ge 3\),那么画个图感性理解一下总是有解的,直接输出 Yes 即可。

    • 如果度数为 \(4\) 的点的个数恰好等于 \(2\),那么再手玩一下可以发现这种情况的图可以被分为两大阵营,一类如下图左边所示,这种情况下原图无法拆成三个环;一类如下图右边所示,这种情况下原图可以被拆成三个环。那么我们如何区分这两类呢?我们找出原图中两个四度点 \(A,B\),稍微分析一下可以发现,一张图属于右边那个阵营,当且仅当 \(A\) 的所有邻居 \(x\)​ 中,满足 \(x\) 能够不经过 \(A\) 到达 \(B\) 的点数 \(\le 2\)​,这个直接枚举一下然后 DFS 一遍即可。

时间复杂度线性。

82. P5362 [SDOI2019]连续子序列

首先思考什么样的序列 \(S\) 能够成为 T.M 序列的子序列。我们发现这个 T.M. 序列的定义有点像一个二叉树的结构,具体来说 T.M 序列可以通过如下方式得到:首先写上一个 \(0\),然后建立一棵以 \(1\) 节点为根无限延伸的满二叉树,\(1\) 号节点的权值为 \(1\),对于每个节点,如果它的权值是 \(0\),那么它的左儿子权值为 \(0\),右儿子权值为 \(1\),否则它的左儿子权值为 \(1\),右儿子权值为 \(0\)。然后将每一层的数字按顺序写下来即可得到完整的 T.M. 序列。

不难发现上面的过程可以用“长”的过程来类比,受到上面的思想的启发,我们不妨也来考虑 \(S\) 是从什么序列 \(T\) 长出来的,对于一个序列 \(S\),分情况讨论:

  • 如果 \(|S|\) 为奇数,那么有两种可能的长法:
    • 一是将 \(S\) 中字符按 \(S_{1},S_{2}\) 配对,\(S_3,S_4\) 配对,\(\cdots\)\(S_{|S|-2},S_{|S|-1}\) 配对,如果配对的两个字符是 \(01\) 则在 \(T\) 末尾插入一个 \(0\),否则如果是 \(10\) 则插入一个 \(1\),否则则说明不可能是通过这种方式长出来的,最后落单的元素 \(S_{|S|}\) 就直接加入 \(T\) 末尾即可。
    • 另一种是将 \(S\)​ 中字符按 \(S_{2},S_{3}\)​ 配对,\(S_4,S_5\)​ 配对,\(\cdots\)​,\(S_{|S|-1},S_{|S|}\)​ 配对,然后按照上一种情况的方式往 \(T\) 里面插入元素。这样开头会有一个落单的元素,在 \(T\) 的开头预先插入一个 \(S_1\oplus 1\)​ 即可。
  • 如果 \(|S|\) 为偶数,那么也有两种可能的长法:
    • 一是将 \(S\)​ 中字符按 \(S_{1},S_{2}\)​ 配对,\(S_3,S_4\)​ 配对,\(\cdots\)​,\(S_{|S|-1},S_{|S|}\)​ 配对的方式插入字符。
    • 还有一种方式是将 \(S\) 中字符按 \(S_2,S_3\) 配对,\(S_4,S_5\) 配对,\(\cdots\)\(S_{|S|-2},S_{|S|-1}\)​ 配对。这样 \(S_1\)\(S_{|S|}\) 均会落单,这可以通过把 \(S_1\oplus 1\) 插到 \(T\) 的开头,\(S_{|S|}\) 插到 \(T\) 的结尾。

可以证明,如果 \(|S|>3\),那么对于任意一个是 T.M. 序列的子序列,总存在唯一的拆分方式,因为对于 T.M 序列中任意一个长度 \(\ge 4\) 的连续段,总存在相邻且相同的字符。这就导致恰好一种拆分方式不合法,因此对于 \(|S|\le 3\) 特判一下,否则如果 \(T\) 符合要求,那么 \(S\) 也符合要求,递归一下即可,时间复杂度 \(\Theta(\sum\limits_{k}\lfloor\dfrac{|S|}{2^k}\rfloor)=\Theta(|S|)\)。即我们实现了在 \(\Theta(|S|)\) 的时间内判定一个字符串是否是 T.M. 序列的子序列。

接下来考虑如何计算答案。我们设 \(f(S,k)\) 表示往 \(S\) 后面添 \(k\)​ 个字符后能够得到多少 T.M. 序列的子序列,如果 \(|S|+k\le 3\),那么特判一下即可得到,否则根据上面的结论,我们枚举得到的字符串是由哪种拆分得到的,这样我们可以得到 \(S\) 对应的序列 \(T\)。进而得到新的 \(k\),继续递归计算即可,时间复杂度 \(T(|S|+\log_2(k))\)

83. CF360E Levko and Game

思维题杀我/dk

不难发现对于每一条权值自定的边,如果它的权值既不是 \(l_i\) 也不是 \(r_i\),那么我们将其调整为 \(l_i\)\(r_i\) 肯定不会影响答案,因为如果它被先手经过没被后手经过,那么我们将它调整为 \(l_i\) 肯定更优;如果它被后手经过而没被先手经过,那么我们将它调整为 \(r_i\) 肯定最优。而如果它既被先手经过也没被后手经过,那不论将其调整为 \(l_i\) 还是 \(r_i\),得到的新图中这条边都要么被先手和后手同时经过,要么同时不经过。

因此我们考虑这样的算法:我们先将所有边的权值设为 \(r_i\),但是这样会导致某些被先手经过但没被后手经过的边的权值过大,这样就导致方案不优,因此我们需要调整。我们设 \(s_1\)\(x\) 的距离为 \(d1_x\)\(s_2\)\(x\) 的距离为 \(d2_x\),那么对于一条权值自定的边 \((u,v)\),如果 \(d1_u<d2_u\),那么我们就将这条边的权值调整为 \(l_i\) 并重新 dijkstra 一遍算出 \(d1,d2\)。如果最终 \(d1_f<d2_f\),那么说明先手赢了,直接输出每条边的边权,否则我们尝试让先手与后手打成平手,即还是先假设所有边权值都是 \(r_i\),然后每次还是求出 \(s_1,s_2\) 到所有点的最短路并枚举所有权值自定的边 \((u,v)\),如果 \(d1_u\le d2_u\),那么我们就将这条边权值调整为 \(l_i\),最后检查是否有 \(d1_f\le d2_f\),如果成立则输出 DRAW,否则输出 LOSE

为什么这样做是正确的?以前一部分,也就是判断答案是否可能为 WIN 的一半为例,对于每条权值自定的边 \((u,v)\),如果 \(d1_u<d2_u\),那么将这条边权值调整为 \(l_i\) 之后,仍然有 \(d1_u<d2_u\),也就是说在最终的局面中,所有存在一种定边权的方式,满足 \(d1_u<d2_u\) 的权值自定边 \((u,v)\) 的权值都被调至 \(l_i\),而其他权值自定边在任何局面下都有 \(d1_u\ge d2_u\),不会对答案产生任何正面影响,因此最终这个局面肯定是最优的。

时间复杂度 \(mk\log m\)​。

84. P3330 [ZJOI2011]看电影

一道出现了 \(10^9+7\) 次的题目(大雾

考虑在 \(k\) 位置后面加入一个 \(k + 1\) 位置并将整个模型变成一个环,那么一种分配方式符合条件当且仅当 \(k+1\) 没有被占。

如果我们每次可以在 \(k+1\) 位置放人,那么理论上来说每个点被占的概率都是相同的,因此满足 \(k+1\) 没有被占的方案数就是 \((k+1)^n·\dfrac{k+1-n}{k+1}=(k+1-n)(k+1)^{n-1}\),答案就是 \(\dfrac{(k+1-n)(k+1)^{n-1}}{k^n}\)

比较烦的一点是要写高精。

85. P5292 [HNOI2019]校园旅行

首先看到这道题我们可以很自然地想到一个 \(m^2\) 的做法:设 \(can_{i,j}\) 表示 \(i,j\) 之间是否存在符合条件的路径,然后类似 BFS 的思路,扩展到一个 \(can_{i,j}\) 时就遍历一遍 \(i\) 的所有邻居 \(x\)\(j\) 的所有邻居 \(y\),如果 \(s_x=s_y\)\(is_{x,y}=0\) 就令 \(is_{x,y}=1\) 并将 \((x,y)\) 这个二元组放入队列里继续 BFS。显然每对边组成的二元组最多被遍历一次,总复杂度就是 \(\Theta(m^2)\)

这样显然过不了,考虑优化。注意到这题 \(m\) 级别比 \(n\) 高很多,对于有这样的性质题,一种思路是仔细分析一样是否所有边都是有用的,如果不是那就踢掉那些无用的边,让边数的级别降得和点数一样。此题就是这种思路,我们将边分为三类:两个端点都是 \(0\)、两个端点都是 \(1\)、两个端点一个是 \(0\) 一个是 \(1\)。我们将这三类边拎出来各建一张图,对于每张图,我们考察每个连通块,找出它的一个生成树并将其加入原图,这样边数就降到了 \(\Theta(n)\) 级别。

但这样做其实是错误的,因为对于一个全由 \(0\) 边组成的连通块,如果我们只找出它的生成树,那就默认所有环的大小都是偶数(因为树是一个二分图),但实则不一定,因此我们需要对由全 \(0\) 边和全 \(1\) 边组成的图的每个连通块,跑一遍二分图染色检验其是否是二分图,如果不是那就在这个连通块对应的生成树上加个自环,不难发现这样原图就与新图等价了。然后跑上面的暴力即可。

时间复杂度 \(n^2+m\alpha(n)\)

86. CF1609F Interesting Sections

讲个笑话,vp 的时候想交这道题的时候 CF 崩掉了,卡了 1h 直到 vp 结束后 3min 才好,好在最后我的第一发提交因为常数太大 T 了,否则就亏大了……

考虑枚举最大值和最小值的 popcount,那么问题等价于,给定一个序列 \(a_i\),其中有一些位置是关键位置,要求有多少个区间,满足其最大值和最小值都是关键位置。

碰到数区间问题无非两个套路:枚举右(左)端点或分治,这次咱们采取前者,我们扫描线式枚举右端点 \(r\),扫描到 \(r\) 时,我们记 \(f_l\) 表示 \([l,r]\) 中最大值是否关键位置 \(+\) \([l,r]\) 中最小值是否是关键位置,那么显然 \(f_l\) 的变化可以通过单调栈求出,那么对于一个右端点 \(r\) 和一个 popcount \(v\),其对答案的贡献就是 \(f_l=2\)\(l\) 的个数。注意到 \(f_l\) 的上界就是 \(2\),因此这个可以通过区间最大值及其出现次数的线段树维护。

算下复杂度,乍一看这个做法复杂度是 2log 的,但实则不是。因为我们单调栈时修改次数均摊下来是 \(\mathcal O(n)\) 的,而查询我们只用用到根节点存储的值,因此虽然查询次数可以达到 \(n\log v\),单次查询是 \(\mathcal O(1)\) 的这一事实导致复杂度也不算太高,这样总复杂度就是 \(n(\log v+\log n)\),可以通过。

注意常数问题!!!!!1111

87. CF1584G Eligible Segments

由于这篇博客里混入了太多奇怪的东西,2021.11.30 决定将博客名改为“杂题选做”

首先,一个点 \(P_k\) 到线段 \(P_iP_j\) 的最小距离 \(\le R\) 等价于 \(P_k\) 到射线 \(\vec{P_iP_j}\) 的距离 \(\le R\)\(P_k\) 到射线 \(\vec{P_jP_i}\) 的距离也 \(\le R\)。那么我们就设 \(is_{i,j}\) 表示是否对于所有 \(k\) 都有 \(P_k\)\(\vec{P_iP_j}\) 的距离 \(\le R\),那么答案就是满足 \(i<j,is_{i,j}=is_{j,i}=1\) 的二元组 \((i,j)\) 的个数。

考虑如何求 \(is_{i,j}\),我们枚举 \(i\),对于每个 \(k\),我们求出 \(P_i\) 到以 \(P_k\) 为圆心 \(R\) 为半径的圆的两条射线的辐角 \(\theta_1,\theta_2\),那么 \(is_{i,j}=1\) 当且仅当 \(\vec{P_iP_j}\) 的辐角在所有 \([\theta_1,\theta_2]\) 的交中,简单判断一下即可。

时间复杂度 \(n^2\)

88. CF633G Yash And Trees

这就是我吗?套路题和思维题都不会做吗?/fn/fn/fn

考虑将树拍平变成一个序列,然后以 DFS 序为下标建立一棵线段树,线段树上每一个节点开一个 bitset 维护这个区间内每种数是否出现过。那么每次进行子树加时,就在对应的区间上进行区间加,这样对应在 bitset 上的变化就是 v = (v << x) | (v >> (m - x)),其中 \(x\) 为增加的量,直接打个标记即可。查询就把对应区间内的 bitset 进行一遍 or 即可。

时间复杂度 \(\dfrac{nm\log n}{\omega}\)

话说这场的 H 我的题解好像还没有补呢,都 8 个月了,估计这辈子都不会补了(

89. CF1019D Large Triangle

首先狠狠吐槽一句,tm 这题明明三角形格点横纵坐标都是整数,因此三角形面积要么是 .0 要么是 .5 才对啊,为什么偏偏 checker 会说我输出的三角形面积等于 \(xxxx.1\)?我实在是不能理解了,难道选手做题是为了适应 checker 的吗?/fn/fn/fn

一开始想着用向量叉积搞,后来事实证明这种东西对于此题而言没前途(

考虑枚举三角形的一条边 \(AB\),我们考虑将所有点按该点到直线 \(AB\) 的有向距离从小到大排序,如果我们能实现这样的操作,那么我们显然向左向右各二分一下即可检验是否存在面积等于 \(S\) 的三角形。

于是问题转化为,我们如何动态地对于一条线段,维护所有点到直线 \(AB\) 的有向距离排好序后的结果。可以注意到,一个点到直线 \(AB\) 的有向距离,可以转化为,过这个点做 \(AB\) 的平行线后,直线与 \(y\) 轴交点的纵坐标。那么我们考虑一个斜率 \(k\)\(-\infty\) 变到 \(\infty\) 的过程,并设想我们过每个点都做了一条斜率为 \(k\) 的直线,这些直线与 \(y\) 轴各会产生一个交点,我们要比较这些交点的纵坐标的大小。不难发现,对于一个点对 \((i,j)\),满足 \(x_i\ne x_j\) 且当 \(k\) 趋近于 \(-\infty\) 时,\(i\) 的截距 \(<j\) 的截距,那么必定存在一个断点 \(k_0\),满足 \(k<k_0\)\(i\) 的截距 \(<j\) 的截距,对于 \(k>k_0\) 的情况则反过来,那么我们考虑将这个过程用个 vector 存下来并将所有这样的事件按 \(k_0\) 排序,再将所有线段按 \(AB\) 的斜率从小到大排序,然后扫描线段时直接在存储的事件的数组里 two pointers 即可,每次遇到一个“\(i\) 的截距反超了 \(j\) 的截距”的事件,我们就交换 \(i,j\) 的排名。显然此时 \(i,j\) 的排名是相邻的,故我们不用进行多余的调整。这样我们就动态地维护了所有点到 \(AB\) 距离的有向距离的大小。

时间复杂度 \(n^2\log n\)

90. AT4519 [AGC032D] Rotation Sort

首先考虑一个非常显然的性质:每个数最多被移动一次,否则我们肯定第一次就会将其移动到它最终的位置。发现这个性质之后,我们就可以很自然地将所有数分为两类:被移动过和没被移动过。我们考虑固定住那些没有被移动过的位置,那么对于两个相邻的没有被移动过的位置 \(l,r\) 之间的位置 \(i\),有两种选择:如果 \(a_i>a_r\),那么只能向右移动,否则由于我们钦定它必须移动,那么我们不妨假设剩余位置必须向左移动。这样我们就可以设计出一个 DP:\(dp_i\) 表示考虑了 \(a_1\sim a_i\),且 \(a_i\) 没有被移动所需花费的最小代价,\(\Theta(n)\) 转移即可,总复杂度 \(n^2\)。可以通过线段树优化到 \(n\log n\),但对于此题来说没有必要。

91. P4798 [CEOI2015 Day1]卡尔文球锦标赛

一道非常基础的题,就当刚刚肝了道毒瘤题之后调节一下心情吧(

首先考虑什么样的序列 \(a\) 符合条件。显然 \(a\) 中出现过的数必须是一段从 \(1\) 开始的连续的前缀 \(1,2,3,\cdots,x\) 对吧,并且如果我们把这些数第一次出现的位置拎出来,这些首次出现的位置肯定是单调递增的。容易证明这是充要条件。

发现这个性质之后我们可以很自然地设计出一个类似于数位 DP 的东西:\(dp_{i,j,0/1}\) 表示考虑了前 \(i\) 个位置,目前出现过的最大的数为 \(j\)​,目前没有 / 有达到上界的方案数,分情况转移即可。直接开数组会 MLE,滚动数组优化一下即可。

时间复杂度 \(n^2\)

讲个笑话,这个模数貌似不是质数,虽然它长得一脸质数的样子(

92. AT2672 [AGC018C] Coins

首先假设所有人都选了金币,令 \(p_i=B_i-A_i,q_i=C_i-A_i\),那么题目等价于选择 \(y\)\(p_i\)\(z\)\(q_i\),满足它们下标集合交集为空,且选出的这 \(y\)\(p_i\)\(z\)\(q_i\) 的和尽可能大。

考虑反悔贪心,我们先贪心地选出 \(p_i\) 最大的 \(y\) 个数和 \(q_i\) 最大的 \(z\)​ 个数,但是这样不一定满足“交集非空”的条件,我们假设此时交集大小为 \(cnt\),那么我们考虑执行 \(cnt\) 次操作,每次操作进行一些微调使交集大小减一,不难发现微调的方式无非以下几种:

  • 选择一个 \(p_i,q_i\)​ 都选择的下标 \(i\)​,和一个 \(p_j,q_j\)​ 都没选择的下标 \(j\)​,去掉 \(p_i\)​ 选上 \(p_j\)
  • 选择一个 \(p_i,q_i\)​​ 都选择的下标 \(i\)​​,和一个 \(p_j,q_j\)​​ 都没选择的下标 \(j\)​​,去掉 \(q_i\)​​ 选上 \(q_j\)​​
  • 选择一个 \(p_i,q_i\)​ 都选择的下标 \(i\)​,一个选了 \(p_j\)​ 没选 \(q_j\)​ 的下标 \(j\)​,还有一个 \(p_k,q_k\)​ 都没选择的下标 \(k\)​,去掉 \(p_i\)​,把 \(p_j\)​ 改为 \(q_j\)​,并选上 \(q_k\)
  • 选择一个 \(p_i,q_i\)​​ 都选择的下标 \(i\)​​,一个选了 \(q_j\)​​ 没选 \(p_j\)​​ 的下标 \(j\)​​,还有一个 \(p_k,q_k\)​​ 都没选择的下标 \(k\)​​,去掉 \(q_i\)​​,把 \(q_j\)​​ 改为 \(p_j\)​​,并选上 \(p_k\)​​

用六个堆维护即可,即维护:

  • \(Q_1\)​ 装有所有 \(p_i,q_i\)​ 都选的 \(i\)​ 的 \(-p_i\)
  • \(Q_2\) 装有所有 \(p_i,q_i\) 都选的 \(i\)\(-q_i\)
  • \(Q_3\)​ 装有所有 \(p_i,q_i\)​ 都没选的 \(i\)​ 的 \(p_i\)
  • \(Q_4\)​ 装有所有 \(p_i,q_i\)​ 都没选的 \(i\)​ 的 \(q_i\)
  • \(Q_5\)​ 装有所有选了 \(p_i\)​ 没选 \(q_i\)​ 的 \(i\)​ 的 \(q_i-p_i\)
  • \(Q_6\) 装有所有选了 \(q_i\) 没选 \(p_i\)\(i\)\(p_i-q_i\)

时间复杂度 \(n\log n\)

93. Codeforces Gym 103409 H Popcount Words

首先看到多串匹配相关问题,果断建出 \(q\) 个模式串的 AC 自动机。

如果我们定义 \(W_{i,j}\) 表示 \(0\sim 2^i-1\) 中所有数的 popcount \(\bmod 2 \oplus j\) 接在一起的结果,其中 \(i\in[0,\lceil\log_2(V)\rceil],j\in[0,1]\)。那么显然所有 \(w(l,r)\) 都可以像线段树区间查询那样拆成不超过 \(2\lceil\log_2(V)\rceil\)\(W_{i,j}\) 拼在一起的结果。因此我们可以将整个文本串看作 \(\mathcal O(n\log V)\)\(W_{i,j}\) 接在一起的结果。

那么我们如何统计 fail 树上每个节点被经过了多少次呢?首先考虑倍增,设 \(to_{i,j,k}\) 表示目前在 fail 树上节点 \(i\),往下读进去一个 \(W_{j,k}\) 后会走到 fail 树上哪个节点。我们再设 \(cnt_{i,j,k}\) 表示有多少次在 \(i\) 处向下接 \(W_{j,k}\) 的机遇,那么我们先按照倍增的套路预处理出 \(to_{i,j,k}\),然后按照顺序依次读进去全部 \(\mathcal O(n\log V)\)\(W_{i,j}\),最后再按照 \(j\) 递减的顺序更新 \(cnt_{i,j,k}\),即用 \(cnt_{i,j,k}\) 去更新 \(cnt_{i,j-1,k}\)\(cnt_{to_{i,j-1,k},j-1,k\oplus 1}\) 即可。

时间复杂度 \((n+\sum|s|)·\log V\)​。

94. CF1418F Equal Product

首先思考一下什么样的 \((x_1,x_2,y_1,y_2)\) 符合条件,这里有一条大概用直觉比较容易发现的性质是,对于符合条件的 \((x_1,x_2,y_1,y_2)\),必然存在整数 \(a,b\),使得 \(x_2=\dfrac{x_1}{a}·b\)\(y_2=\dfrac{y_1}{b}·a\)\(\dfrac{x_1}{a},\dfrac{y_1}{b}\) 均为整数。

证明:考虑设 \(d=\gcd(x_1,x_2)\),然后令 \(a=\dfrac{x_1}{d},b=\dfrac{x_2}{d}\)(说白了就是设 \(\dfrac{b}{a}\) 表示 \(\dfrac{x_2}{x_1}\) 约分以后的结果),那么显然 \(\dfrac{x_1}{a}=d\) 为整数,而 \(\dfrac{y_1}{b}·x_1=\dfrac{x_2}{b}·y_2=d·y_2\) 为整数,又根据 \(\gcd(a,b)=1\) 可知 \((x_1,b)=1\),因此必然有 \(b\mid y_1\),证毕。

因此我们考虑枚举 \(x_1\) 时,顺带枚举符合条件的四元组所对应的 \(a\),那么思考一下什么样的二元组 \((y_1,b)\) 会符合条件,归纳一下就是下面三条:

  • \(\lceil\dfrac{L}{x_1}\rceil\le y_1\le\min(\lfloor\dfrac{R}{x_1}\rfloor,m)\)
  • \(\dfrac{x_1}{a}·b\le n\)
  • \(a<b\)

我们考虑正序枚举 \(x_1\),那么第一条中 \(y_1\) 的范围的左右端点都是不升的,这样我们可以通过 two pointers 将所有符合条件的二元组 \((b,y_1)\) 扔进一个 set 中,对于后两条限制,显然在符合第三条限制的前提下,\(b\) 最小的那个最有可能符合条件二,因此我们直接在 setlower_bound 检验即可。

算下复杂度,set 有个 log,而我们 \(x,a\) 的总枚举量是调和级数级别的,也就是 \(n\ln n\),因此总复杂度 \(n\ln n\log n\),可以通过。

95. CF1519E Off by One

由于每个点必须要移动,因此我们考虑对于每个点 \(i\),求出其向上和向右移动后得到的两个点 \(P_i,Q_i\),然后将所有出现过的斜率看作一个点并在 \(P_i,Q_i\) 的斜率所对应的点之间连边。这样问题可以转化为,给你一张图,要你选出一些不相交的二元组 \((e1_i,e2_i)\),满足选出的二元组中两两之间没有公共元素且 \(e1_i,e2_i\) 之间有公共点,要你求最多能选出多少个二元组。

针对上面的问题,我们首先大胆猜测:对于每个连通块,假设连通块中有 \(e\) 条边,那么该连通块中最多可以选出 \(\lfloor\dfrac{e}{2}\rfloor\) 个二元组,即,假设图中有 \(k\) 个连通块,第 \(i\) 个连通块中有 \(e_i\) 条边,那么答案就是 \(\sum\limits_{i=1}^k\lfloor\dfrac{e_i}{2}\rfloor\)

事实的确如此,考虑如何构造:对于每个连通块,我们先对其进行一遍 DFS,也就是找出它的一棵 DFS 树(虽然我们并不用显示地将树建出来,但是大体思想就是如此),然后对于每个点,有可能所有与其相连的边已经全部匹配完,也有可能与其相连的边中,恰有一条边没有被匹配(如果出现了多余两条边没有被匹配,那么我们可以贪心地将这两条边配对,这样肯定更优)。因此我们记 \(mch_u\) 表示与 \(u\) 相连的边中,没有被匹配的边的编号,特别地,\(mch_u=0\) 则表示所有与 \(u\) 相连的边都被匹配。那么我们考虑 DFS \(u\) 的一个儿子 \(v\) 时,分情况讨论:

  • 如果 \(mch_v\ne 0\),则将 \(u,v\) 之间的边与 \(mch_v\) 配对并令 \(mch_v=0\)
  • 否则,如果 \(mch_u\ne 0\),则将 \(u,v\) 之间的边与 \(mch_u\) 配对并令 \(mch_u=0\)
  • 否则令 \(mch_u\)\(u,v\) 之间的边的编号。

如此贪心下去即可,总复杂度 \(n\log n\),瓶颈在于求出所有出现过的斜率。可能可以做到 \(\mathcal O(n)\)

96. CF1609G A Stroll Around the Matrix

u1s1 感觉这个题其实还挺一眼的吧,不知道怎么被评到 3k 的.jpg(

首先考虑什么样的路径是最优路径。我们先不妨假设我们先一直向右走,再一直向下走,即 \((1,1)\to(1,2)\to\cdots\to(1,m)\to(2,m)\to\cdots\to(n,m)\),但是这样显然不一定是最优解,因此考虑调整。调整的第一步显然是将 \((1,m-1)\to(1,m)\to(2,m)\) 调整为 \((1,m-1)\to(2,m-1)\to(2,m)\),显然后者代价比前者更优,当且仅当 \(a_2+b_{m-1}<a_1+b_m\)。再者就是将 \((1,m-2)\to(1,m-1)\to(2,m-1)\) 调整为 \((1,m-2)\to(2,m-2)\to(2,m-1)\),以及 \((2,m-1)\to(2,m)\to(3,m)\) 调整为 \((2,m-1)\to(3,m-1)\to(3,m)\),以此类推。按照这样的方式继续手玩下去可以发现,在最终的状态中,假设我们在点 \((i,j)\),那么我们会往下走,当且仅当 \(j=m\),或者 \(i\ne n\)\(a_{i+1}-a_i<b_{j+1}-b_j\)

我们考虑设 \(pos_i\) 表示我们处于第 \(i\) 行时,会在哪个位置首次向下走,由于 \(n\) 很小并且题目中 \(a,b\) 序列都是下凸的,因此对于同一行 \(i\),必然存在一个断点 \(j\),使得对于 \(j\) 左边所有位置,当我们位于 \((i,j)\) 时都会向右走,而对于 \(j\) 右边所有位置,当我们位于 \((i,j)\) 时都会向下走。且 \(pos\) 数组也是单调不降的。这样一来问题就好办了,由于 \(n\) 很小,因此对于每次修改,改完之后都可以直接线段树二分修改 \(pos\) 数组,而答案即为 \(\sum\limits_{i=1}^n(a_i·(pos_i-pos_{i-1}+1)+\sum\limits_{j=pos_{i-1}}^{pos_i}b_j)\),这个也可以每次 \(\mathcal O(n\log m)\) 地求。比较麻烦的是要实现单点加求三阶前缀和,用树状数组维护平方项、一次项和常数项能够获得常数较小的实现。

时间复杂度 \(\Theta(nm\log m)\)​。

97. NFLSOJ #795 【五校国集集训 Day1】数学题(math)

首先考虑求出给定的 \(n\) 个向量的一组基 \(\mathcal B\)。那么非常显然的一个性质是,对于不在 \(\mathcal B\) 中的向量,如果我们翻转其中任意一位上的值,矩阵的秩肯定不会减小,因为矩阵仍存在线性无关的向量集合 \(\mathcal B\)。而我们发现,对于 \(\mathcal B\) 中的某些向量,这个性质也是成立的,比方说给出的向量集合为 \(\{100,011,111\}\),我们通过一遍线性基求出的基 \(\mathcal B = \{100,011\}\),但实际上,不论我们去掉三个向量中的哪一个,剩余部分的秩仍然是 \(2\),也就是说不论我们翻转哪一个位置,矩阵的秩总是不降的。

那我们如何找出所有满足“翻转其中任意一位,矩阵的秩都不降”的向量呢?首先不在 \(\mathcal B\) 中的向量肯定要归为其中,而对于在 \(\mathcal B\) 中的向量,我们假设 \(\mathcal B = \{x_{b_1},x_{b_2},\cdots,x_{b_k}\}\),并将所有不在 \(\mathcal B\) 中的向量都表示为 \(\mathcal B\) 中向量的线性组合,即假设 \(x_i=c_{i,1}x_{b_1}+c_{i,2}x_{b_2}+\cdots+c_{i,k}x_{b_k}\),其中 \(c_{i,j}\in\{0,1\}\),那么一个 \(x_{b_j}\) 符合上述要求,当且仅当 \(\exists i,s.t.c_{i,j}=1\),因为就算把 \(x_{b_j}\) 去掉之后,加入符合上述要求的 \(x_i\),得到的向量集仍是线性无关的。

而我们还可以发现一个性质,就是对于符合上面要求的向量,它们的答案都是相同的。具体来说我们考察每个 \(e_j\),即只有第 \(j\) 维为 \(1\) 的向量,如果它在 \(\mathcal B\) 生成的空间中,那么说明对于符合上面要求的向量,它与 \(e_j\) 的和也在 \(\mathcal B\) 生成的空间中,所有这些向量的答案的第 \(j\) 位就是 \(0\),否则所有这些向量第 \(j\) 位的答案就是 \(+\)

那对于别的向量,也就是去掉这个向量后,矩阵的秩必然减小的向量呢,首先一个显然的性质:翻转这些向量的任何一位后,矩阵的秩必然不增,因为去掉这个向量后,矩阵的秩减少 \(1\),而加入一个向量最多使矩阵的秩增加 \(1\)。那么翻转什么样的位后,答案减小 \(1\) 呢?我们还是考虑将 \(e_j\) 拆成 \(\mathcal B\) 中元素的线性组合。如果 \(e_j\) 无法表示,那么秩肯定不变,否则,如果 \(e_j\) 的表示中包含 \(x_i\),那么我们考虑再将 \(x_i+e_j\)​ 表示成 \(\mathcal B\) 中元素的线性组合,显然 \(x_i+e_j\) 的线性组合中不会包含 \(x_i\),因为 \(x_i\) 的表达式中有个 \(x_i\)\(e_j\) 的表达式中也有个 \(x_i\),二者相加,在模 \(2\) 意义下消掉了,而其他向量的表示中也没有 \(x_i\),因此矩阵的秩减小,否则不难说明矩阵的秩不变。

bitset 模拟上面的过程即可,时间复杂度 \(\dfrac{n^3}{\omega}\)​,如果视 \(n,m\)​​ 同阶。

98. CF1530G What a Reversal

What a Problem!

首先考虑在变换前后有没有什么量是不变的。显然 \(1\) 的个数肯定不会变对吧,如果 \(s,t\)\(1\) 的个数不同那就直接 GG 了。这个直接特判一下即可。

我们记 \(s,t\)\(1\) 的个数为 \(m\),对于 \(k=0\)\(k>m\) 的情况,显然只有 \(s,t\) 完全相同才有可能有解,这个特判一下即可。对于 \(k=m\) 的情况我们也需特判一下,这个大概就分翻一次、翻两次、翻三次分类讨论一下,可能细节略有点繁琐。

下面重点讨论 \(k<m\)​ 的情况,首先发现操作可逆,因此我们按照套路将 \(s,t\) 全变成一个字符串,然后正序输出 \(s\) 的操作序列并倒序输出 \(t\) 的操作序列。考虑一次操作的本质是什么,我们假设 \(s\)\(1\) 的位置分别是 \(p_1,p_2,\cdots,p_m\),方便起见假设 \(p_0=0,p_{m+1}=n+1\),我们再设 \(d_i=p_{i+1}-p_i-1\)​,那么可以发现一次操作等价于:

  • 选择一个 \(i\in[0,m-k]\)​​,reverse 子段 \(d_{i+1},d_{i+2},\cdots,d_{i+k-1}\)​​,同时选择一个 \(j\in[-d_i,d_{i+k}]\)​​,并令 \(d_i\)​​ 加上 \(j\)​​,\(d_{i+k}\)​​ 减去 \(j\)​​。

下面考虑怎样构造,首先是 \(k\)​​​​ 是奇数的情况,我们考虑将两个字符串都调整至 \(d_0=n-m,d_i=0(i\in[1,m])\)​​​​ 的状态。我们首先先将 \(d_{k+1},d_{k+2},\cdots,d_m\)​​​​ 归零,这个就每次选择 \(j=d_{i+k}\)​​​​ 即可清空 \(d_{i+k}\)​​​​。然后我们考虑对于奇数步,我们令 \(i=0,j=d_k\)​​​​,这样相当于翻转 \(d_1\sim d_{k-1}\)​​​​ 并将 \(d_k\)​​​​ 清空全部送给 \(d_0\)​​​​;对于偶数步,我们选择 \(i=1,j=d_{k+1}=0\)​​​​,这样相当于翻转 \(d_2\sim d_k\)​​​​​​​,不难发现这样操作下去,\(d\)​​​​ 数组会依次发生以下变化(其中红色代表对应的 \(d\)​​​​ 值已经变为 \(0\)​​​​:

  • \(d_0,d_{k-1},d_{k-2},\cdots,d_1,\color{red}{d_k}\)​​
  • \(d_0,d_{k-1},\color{red}{d_k}\color{black}{,d_{1},d_2,\cdots,d_{k-2}}\)​​
  • \(d_0,d_{k-3},d_{k-4},\cdots,d_1,\color{red}d_k\color{black},d_{k-1},\color{red}d_{k-2}\)
  • \(d_0,d_{k-3},\color{red}{d_{k-2}}\color{black}{,d_{k-1},}\color{red}{d_k}\color{black}{,d_1,d_2,\cdots,d_{k-4}}\)

不难发现在上面的过程中,咱们采用每一轮隔一个清一个的策略,即在奇数次操作依次将 \(d_k,d_{k-2},d_{k-4}\cdots,d_1,d_{k-1},d_{k-3},\cdots d_2\) 清空,由于 \(k\) 是奇数,故每个 \(d_i\) 都会被清到,因此进行 \(2k\) 次操作即可清空 \(d_1\sim d_k\),总操作数 \(2k+(m-k)=m+k\le 2n\)

接下来考虑偶数的清空,手玩一下可以发现 \(k\) 为偶数时不一定有解,因为不论你怎么 reverse,都有奇数位上的 \(d_i\)​ 之和不变,偶数位上也是如此,因此如果 \(s,t\) 奇数位上的 \(d\) 之和不同那就直接 GG 了,否则我们考虑如下构造方式:

  • 首先还是将 \(d_{k+1}\sim d_n\) 全部清空,构造方式同 \(k\) 为奇数的清空。
  • 然后在奇数轮我们还是选择 \(i=0,j=d_k\),在偶数轮我们则选择 \(i=1,j=-d_1\)

我们还是手动模拟一下上面的过程:

  • \(d_0,d_{k-1},d_{k-2},\cdots,d_1,\color{red}{d_k}\color{black},d_{k+1}=0\)
  • \(d_0,\color{red}{d_{k-1},d_k}\color{black},d_{k-2},\cdots,d_1,d_{k+1}\)
  • \(d_0,d_2,d_3,\cdots,d_{k-2},\color{red}{d_{k},d_{k-1},d_1}\color{black},d_{k+1}\)
  • \(d_0,\color{red}{d_2,d_1,d_{k-1},d_k}\color{black},d_{k-2},d_{k-3},\cdots,d_4,d_3,d_{k+1}\)

不难发现在上面的过程中,我们不断把奇数位上的 \(d\) 丢给 \(d_{k+1}\),把偶数位上的 \(d\) 丢给 \(d_0\),因此最后得到的一定是 \(x,0,0,0,\cdots,0,y,0,0,\cdots\)​ 的形式。符合要求。

时间复杂度 \(n^2\),瓶颈在于每次操作后都要 reverse 重新算 \(p,d\)

99. CF1530H Turing's Award

咦?时隔 INF 天,tzc 竟然来补题解了,incredible(

首先考虑将整个过程倒过来处理,问题转化为有一条数轴,你当前在 \(0\) 的位置,有一个排列,每次你可以走到相邻两个位置中的一个,如果那个位置上没有数就在那个位置上填上 \(p_i\),求得到的 LIS 的最大值。

不难发现最优策略中,任意时刻肯定是恰有一个区间上有数,并且对于我们不钦定在 LIS 上的数我们肯定不会把它写到纸上,否则从区间的一端走到另一端所需的代价会更大。考虑以此为状态设计 DP。设 \(dpl_{i,j}\) 表示目前人在左边,LIS 长度为 \(j\),最左边的在 LIS 上的数为 \(i\),最右端的数的最小值,再设 \(dpr_{i,j}\) 表示目前人在右边,LIS 长度为 \(j\),最右边的在 LIS 上的数为 \(i\),最左端的数的最大值。考虑如何转移,以 \(dpl\) 为例,\(dpr\) 道理类似:

  • 如果上一步还在左边,那么有 \(dpl_{i’,j-1}\to dpl_{i,j}\),能进行这样的转移的条件是 \(i’>i\)\(pos_{i’}>pos_i\),其中 \(pos_x\) 表示 \(x\) 这个数在排列中的位置。
  • 如果上一步在右边,那么有 \(i’\to dpl_{i,j}\)​,能进行这样的转移的条件是 \(dpr_{i’,j-1}>i\)​ 且 \(pos_{i’}-pos_i\ge j-1\)

直接枚举 \(i,j,i’\)​ 转移是三方的,不过注意到转移可以写成前缀 \(\max/\min\) 的形式,因此可以用树状数组找出最优决策点,复杂度变成了 \(n^2\log n\),但还是不够。注意到题面中有个“排列 \(p\) 随机生成”的条件。根据经典结论,随机排列的 LIS 长度期望是根号级别的,因此我们猜测答案期望也是根号级别的,事实确实如此。实践证明 \(j\) 枚举到 \(285\) 即可,这样复杂度就变成了 \(285n\log n\),常数略大,但由于时限很大,可以通过。

具体实现时还有不少细节需要注意,比如此题边界条件非常值得思考,不能简单地 \(dpl_{i,1}=dpr_{i,1}=i\),因为无论如何 \(p_n\) 都是要写出来的,因此要分 \(p_n\) 在 LIS 上和不在 LIS 上处理。

100. P6845 [CEOI2019] Dynamic Diameter

简单题。然鹅我一开始竟然不会,ymx 竟然一开始想 LCT,wjz 竟然一开始想动态 DP,震撼震撼(

考虑经典结论:点集的并的直径属于点集的直径的并,这样我们可以在 \(\mathcal O(\log n)\)​ 的时间内通过两个点集 \(U,V\)​ 的直径合并得到 \(U\cup V\)​ 的直径,然后 DFS 序+线段树维护区间直径即可,修改一条边的边权时,我们只用更新包含这个点的区间的信息即可。

时间复杂度 \(n\log^2n\)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM