record 5.27-5.31
* [YDRS#007 D]
咋这么多人过这个题。
我们先给出一个 \(O(n)\) 做法。显然,只需要找到交换任意两个元素的方法就行了。
比方说你有 \(1,2,3,4,5\),想要交换 \(2,4\),只需要 \(1,2,3,4,5\to 5,4,3,2,1\to 1,4,3,2,5\)。所以我们现在可以做到 \(2n\) 次操作。当然如果当中有空集的话还不太一样,但是应该都可以操作。
然后你发现要求是 \(120\),\(n\le 20000\),而 \(\log_2(20000)\approx 14.3,\sqrt{20000}\approx 141.4\),看起来像是小常数根号或者很大常数的 log。能做到低于线性其实并不意外,因为我们一次操作其实是很多次交换操作的打包。
我们把目光转向操作的性质。这操作是对全局进行的,因此如果你要对一个部分单独操作的话,可能还要进行一些额外的处理。然后每个区间内部的顺序是没有发生变化的,这某种意义上的保序性可以帮我们保留已经排序好的部分。
显然的一点是,如果有两个相邻数它们值域也是相邻的,那我们完全可以把它们绑定到一块,接下来视为更小的子问题来处理。
不会这种题/ng。
阅读了 sol。
sol 说我们可以在每次操作后立刻对所有元素进行一次 \(k=n\) 的操作,这样操作就相当于是每个区间内部进行翻转。以这个操作为基本操作。
考虑对 01 序列进行排序,这个是简单的。你考虑每个连续段,我们对连续段进行分治,合并的时候只需要一次操作就可以了。这复杂度只需要 \(O(\log n)\)。
考虑原问题。我们把 \(\ge mid\) 看成 \(1\),\(<mid\) 看成 \(0\) 进行一次排序。然后分治下去。
并且没必要每次都真的进行 \(k=n\) 的操作,可以假装自己进行了,然后到最后的时候 check 一次就行了。
复杂度 \(O(\log^2n)\)。其实是个很不错的题。
这次有点卡在第一步上了。构造题很多都是要发现一些特殊的东西,就是说你没必要把所有东西都研究清楚,你只要找到一个足够好用的东西就行了。
~ Luogu P8859
type1 就是发现一个数需要被冒泡当且仅当这个数前面有比它大的数。然后我们从大往小填每个数,如果不在开头就造成贡献。
type2 要复杂一点。我们的一个直观想法就是维护每个位置作为开头时的答案,然后取最小值。分析发现,如果在一个缝当中插入一个数,相当于把全局答案加 \(1\),然后再添加一个跟这个缝原来答案相同的数。
进一步,可以想象成是这个缝的数 \(x\) 分裂成 \(x-1,x\)。
进一步,把这个过程想象成是一棵有根树的生成过程,发现这个过程跟一个父亲比孩子标号要大的树是等价的。所以我们对这样的东西计数就可以了。
* [YDRS#007 E]
我们先考虑单次询问。显然这个 \(F(S)\) 的定义非常奇怪,我们考虑把它说成人话。
发现这个过程很像某种“抹匀”操作。我们发现等价于寻找最大的 \(x\) 满足 \(\le x\) 的至少有 \(x\) 个,如果存在这样一个 \(x\),我们就可以声称 \([1,x]\) 都可以被填满。并且假设最后真的只能填满 \([1,x]\),\(x\) 一定满足这个条件。
或者说,记前缀和是 \(s\),我们其实要找最大的 \(x\) 满足 \(s_x-x\ge 0\)。我们可以倒着找。
当然,可以在线段树上二分,每个节点维护区间内的最大值即可。
当然,回到原问题上,扫描 \(r\),我们可以变成线段树维护值域上的 \(x\),存放最大的 \(l\) 满足 \(F([l,r])\ge x\)。
阅读了 sol。
我们对值域从大到小扫描,维护每个区间的答案。
注意到如果一个区间包含另一个区间,那么大区间的答案一定更大。所以我们对有包含关系的,可以只算更大的。所以我们只需要维护互不相交的若干个区间,以及支持它们的插入和删除。
这样,每次修改一个位置的值的时候,会影响连续的一段区间,我们只需要找出什么时候这个区间里第一次 \(\ge 0\) 就可以了。然后把这样的区间删除掉,继续引入进来其他的区间。
复杂度 1 log。不想写。
[CF1975 D]
场上被这题创飞了。不过我场上确实有点唐。
这个题是说有一个树,上面有两个棋子 A B,你每一轮可以移动两个棋子各一步,我们称一个节点是合法的,当且仅当存在两个时刻,使得该节点先被 A 走过,然后又被 B 走了。你的目标是把所有点都变成合法的,问你最少需要多少时间。
显然,如果只有一个棋子,我们走的路是一个环路去掉根到最深点的路径。加入另一个棋子之后,考虑这个棋子的位置。如果它不在最深点的子树当中,那我们调整顺序,优先去走它所在的子树,然后大家一起走就行了。这样,答案只会是 \(A\) 的答案 \(+1/+0\)。
我们猜测答案应该是俩人先碰头,然后正常走。
如果这个棋子就在最深点的子树当中。显然有一个合法解是俩人各走各的,答案是 \(A\) 的答案加 \(dep_B\)。
哎呀糖了。你考虑 B 第一次真的染上颜色是在节点 \(x\)。现在它要把所有点都染完会有一个至少需要的时间,如果 \(A,B\) 在一起显然可以取到这个至少需要的时间。
然后你考虑自己到底要选哪个点。你的贡献是 \(\max(dis(A,x),dis(B,x))+val_x\),注意到你 \(x\) 移动一格 \(val_x\) 至多 \(-1\)。你考虑跟 \(A,B\) 中点进行比较发现不如中点。所以就做完了。
~ [CF1975 F]
看起来有点厉害的。
人话说就是,你需要找到所有的满足一些条件的长度为 \(n\) 的二进制串 \(x\),对每个 \(y\in [0,2^n)\) 都会有一个集合,指定 \(|x\cap y|\) 可以从哪些值当中选。
这限制感觉有点强的。
阅读了 hint。
你发现如果确定了前 \(x\) 个数,那么只剩下 \(2^{n-x}\) 个限制了。这样我们爆搜总复杂度就是 \(O(n2^n)\)。
[CF1975 G]
这个题我见过的,好像 spx 之前给我看过。怎么 cf 还有搬题怪啊。
我们考虑从前往后一个个匹配,直到遇到第一个 * 为止。类似地,从后往前这么做。
如果上下都有 *,显然答案是 Yes。否则上面左右各有一个 *,中间可能有点别的,相当于要从下面找一个区间,能跟上面的中间部分匹配。
如果此时下面还有一个 * 显然就结束了。所以下面没有 *。问题转化为给你一个可能有 * 的串 \(s\) 和一个没有 * 的串 \(t\),能不能找到 \(t[l,r]\) 与 \(s\) 匹配。
\(s\) 没有 * 就是普通通配符,可以 FFT。
然后你考虑 \(s\) 被 * 分成了若干部分,你从前往后匹配,肯定是希望前面的部分匹配结束的位置尽可能靠前。那我们就记 \(dp_i\) 表示这个东西。
现在,你需要解决一个子问题。给你两个不含 * 的串 \(s,t\),问你能匹配上 \(s\) 的 \(t[l,r]\),\(r\) 最小是多少。其中 \(\sum|s|\) 有保证。
你当然想每次 FFT,但是 \(\sum|t|\) 并没有保证。所以我们考虑倍增,这样复杂度是 \(O((ans+t)\log n)\),最后总复杂度至多 2 log。
事实上,我们可以每次往后算 \(2|t|\) 个,如果有就有了,如果没有就可以删掉 \(|t|\) 个,所以复杂度是 1 log。
不想写了。
* [CF1977 E]
有点意思。
相当于给我们一张 DAG,这张 DAG 满足对于任意三个点 \(1\le i<j<k\le n\),\(k\to j,j\to i,k\to i\) 至少有一个成立。
然后让你把图划分成两个部分,每个部分都要满足对于任意两个点 \(1\le i<j\le n\),\(j\to i\)。
分析一下,我们猜测最后划分的每个部分事实上都必须是一条链。这是可以证明的。所以我们是要找出来两条链。
然后我们自然会好奇,它给的条件能分析出怎样的图出来。
因为 \(n\) 没有入度,所以它必须是其中一个链的开头。
2 hard 4 me。
看了 sol 说证明存在解可以使用 Dilworth 定理。所以我们先看一下 Dilworth 到底是啥东西。
Dilworth 定理是关于偏序集上链和反链的关系的。这里偏序集满足自反性、反对称性、传递性,链指的是一个满足全序关系(加上连接性)的子集,反链指的是两两不可比的子集。最长反链的大小也被称为这个偏序集的宽度。
Dilworth 定理声称,最长反链大小,与最小不交链覆盖是相等的。
证明使用数学归纳法。我们对偏序集大小进行归纳。
如果这个集合 \(S\) 不存在长度 \(>1\) 的链,那说明这个偏序集两两不可比,已经证毕。否则提取出一个链 \(\{m,M\}\),这里分别代表这个链的最小/大元素,并且要求 \(m,M\) 分别是极小/大的。
考虑集合 \(S/\{m,M\}\) 的最长反链,如果 \(<d\),那么根据归纳假设,它可以被 \(d-1\) 条链覆盖,我们已经证毕。
否则,说明 \(=d\)。我们提取出它的一个最长反链 \(A\) 出来,并定义 \(S^+,S^-\)。
显然,\(S^+\cup S^-=S\),否则与最长反链矛盾;\(S^+\cap S^-=A\),这个也可以证;\(|S^+|,|S^-|<|S|\),这是因为 \(m\not\in S^+,M\not\in S^-\)。
分别对 \(S^+,S^-\) 进行归纳,我们在每个部分中恰好会得到 \(d\) 条分别包含 \(A\) 当中各个元素的链。我们设这样的链分别为 \(C_a^+,C_a^-\),那么构造 \(\{C_a^+,a,C_a^-\}\) 即可。
我们证完了,这东西给出了一个归纳做法,对我们的做法还是有一些启示的。
然后发现 sol 的做法跟我有点像的。就是我们从大到小考虑加入每个元素,然后维护三个(我是两个)链。然后为了让当前需要加入的数 \(x\) 能接上去,你最好保证那两个链的末尾互相之间没有连边。我就是这个东西做不到。
它就是发现如果 \(x\) 能同时被两个链到达,就把它扔到第三个链里头,然后直到遇到一个点没办法接到第三个链,那就把它俩分别扔到两个链里头就行了。
不是很懂这种题。
?* [CF1795 H]
这题我大概做不出来,但是让我们看看我能推到哪。
它定义 core 是字典序最大的子串。那显然 core 一定是一个后缀,我们对所有后缀排序之后就出结果了。
然后它给了我们一些字母,我们可以任意排列这些字母,目标是让 core 最小。你可能会想直接把 z 全排到最后就行了,但事实上 zaaaz 可能更优一点。
我们可以想象成一开始是 zzzzzz,然后你要往当中的空隙插入一些更小的字母来把字典序变小。如果 a 能够覆盖,那我们肯定让它先覆盖一轮,这样就插入进去 a 了;如果不够覆盖,但是加上 bc 能够覆盖,那我们就按照 abc 的顺序依次放就行了,这样最后能得到 zc*。
呃呃有点复杂了,现在不是很想看。感觉这两天很失败啊。
~ [mxr15 A]
这不是 spx 之前给我看的那个题吗。但是当时并不会做,也没听懂咋做的,现在让我来看看。
首先我们找到这样的合法区间 \((l,r,x)\) 表示 \(l,r\) 可以全部合并起来,最后变成 \(x\) 这个数。事实上只需要 \(l,r\),\(x\) 是可以被计算出来的。
然后注意到对于同一个 \(x\),显然 \([l,r]\) 是互相不包含的,也就是说对一个左端点 \(l\) 而言最多只存在一个右端点 \(r\) 是合法的。那我们记这个右端点是 \(f_{x,l}\),合并可以考虑 \(f_{x,l}=f_{x-1,f_{x-1,l}+1}\)。而显然 \(x\) 的取值范围只有 \(V+\log n\approx 20\),然后套上一个询问大概就是套一些 ds 就可以做了。总之我们现在会处理静态问题了。
考虑修改。你发现上面这个 \(f\) 变化可能会相当大。举个例子来说,如果你有很长一段连续的 \(1\),然后突然把中间一个给改了,那会发生很大变化。这变化我不清楚是否能维护,暂且认为不能吧。
我们可能得再发现一点性质。
这个东西限制感觉比较严,合成不是那么随意的,这既是限制也是条件。并且你发现手玩的时候,会出现一些不敢合成的情况,这是因为你不清楚接下来这次合成操作是不是有用,甚至不清楚是不是合成之后就寄了。
换一个做法。我们要让自己敢合成。
你考虑按照值域从小到大的顺序,依次把所有值是 \(x\) 的全都合成成一个更大的。这会遇到一个问题,如果有一个长度为奇数的 \(x\) 连续段,那么你肯定是要剩下一个数,放弃其中一侧了,你怎么知道放弃哪一侧?很简单,我们在两侧同时添加上最后合成的结果,同步进行到最后,只保留答案更大的就行了。
这做法应当是正解,因为我依稀记得当初就是这做法。问题是我们怎么去维护这一过程。
考虑使用线段树。如果我们当前的目标是合并该节点内部所有值为 \(x\) 的段,使得 \(x+1\) 最多的话,显然可以类似于最大子段和的方式来合并。
复杂度 \(O(n(V+\log n)\log n)\)。感觉很对,写一发。
感觉不对,这东西根本没办法合并。
阅读了一些 tip。
对于一个区间而言,我们可以把一定会压缩的先给压缩了,然后再考虑跟别人的合并。注意到一个谷是一定不会被外界所影响的,所以我们可以事先把所有谷都给合并了。那接下来就变成了左右两个长度 \(O(V)\) 的向下段,以及中间一些被“隔断”的部分。隔断部分记录最大值即可。
感觉我又烂完了。
[mxr16 A]
根号重构即可。sol 说有 2 log 做法,是什么平衡树套平衡树。我可能懂了一点,大概就是你插入的时候插入到它的 dfn 位置,然后每次查询 split 出询问区间出来,pushup 的信息是一棵可持久化平衡树。但是咋修改啊?链上修改是不是只能差分或者剖分啊?
* [mxr16 B]
怎么过的比 A 还多。
你发现 LIS 不超过 \(2\) 很对,这个 \(2\) 你可以理解成不存在一个点,它前面后面都有能拼上的。
我们首先考虑一下,如果没有锁死某个位置的值怎么做。
你考虑 \(n\) 插入在 \(p\) 位置,那么在 \(p\) 之前的数肯定得严格递减排列。\(p\) 之后的比较麻烦,我们先考察前面对后面的影响。发现现在后面的数里头会有 \(x\) 个在前面有比它小的,以及 \(y\) 个没有限制的。并且这 \(x\) 个数一定是你选的里头最大的若干个。
所以这 \(x\) 个数也得降序排列,问题变成你有 \(x+y\) 个数,要求 LIS 不超过 \(2\),并且最大的 \(x\) 个数降序排列。
你考虑这 \(x\) 个数之间的空隙,因为只能插比它们要小的数,所以插入的数后面已经有比它大的了,所以它前面不能再有比它小的。所以每个块内部得是降序排列,并且两个不同块之间,前面不能有比后面小的。也就是说,你的排列方法唯一地被你的划分方式确定了,方案数就是 \(v_0+\dots+v_x=y\) 的非负整数解个数,我们都知道这是 \(\binom{x+y}{x}\)。
所以
我写个程序看看对不对。
上面这个错完了,具体来说我们最后一段并没有这样那样的限制,所以最后一段写出来其实是递归下去的形式。那就没救了,写出来特别麻烦。
换换思路。大眼观察发现,满足条件的一定可以被至多 2 个不交下降链所覆盖。事实上这是由 Dilworth 定理保证的。
如果你要用这个计数的话,问题出在,一个方案可能会被计算很多次。
看了一眼 tip。
既然这样,我们就钦定一种计算方案让它只被算一次。最简单的方法就是钦定其中一个下降链是前缀 min 链。容易知道这种方案一定是合法的。
然后你发现不了,如果一个数在单调栈当中,那么 \(p_x\le n-x+1\),这个是跟 LIS 的条件有关的。
为了方便,我们把条件对偶一下,变成 LDS 长度不超过 2,这样条件变成了 \(p_x\ge x\)。
考虑这样一个前缀最大值序列,其实唯一对应于一条 \((0,0)\to(n,n)\) 的路径,你可以认为每一列第一次向右移动到达的点就是当前前缀最大值。所以只需要统计 \((0,0)\to(n,n)\) 不经过 \(y=x\) 的方案数就行了。
然后考虑加上限制。如果这限制满足它是前缀最大值,那就相当于强制要求 \(A\) 这一列是从 \(B\) 这个位置向右挪过来的,这个显然可以拆成两部分来做。如果它不是前缀最大值,那我们可以把值翻转的同时把位置也翻转,这样两个位置的相对大小关系不会改变,但是就变成前缀最大值了。
想到了一点 dilworth,但是没想到钦定,这个不应该。后面这个单调栈太神秘了,但是其实观察可以发现这个是 catlan 数,没看出来确实不应该。
[arc116 D]
感觉有点唐了。
一开始我想的是用前面的确定 \(a_n\),然后变成要求 \(sum+xor=m\),发现没啥用。
后来一想,我们直接数位 dp 就行了啊。这样做复杂度好像是个 \(O(n^2\log m)\),所以我的做法有点弱了。
然后看了一眼 sol,它写的同一个东西,只不过根据 \(m\) 很小进行了一个特殊的做。
[arc116 E]
简单题,但是我感觉中间凭借直觉跳了很多步,我尝试一步步慢慢写。
首先给你一个方案答案是多少,你发现是每个位置到最近点的距离的最大值。然后这种东西的套路就是二分答案,所以想一下能不能判定。
转成判定之后,相当于每个点都要求距离它 \(k\) 内至少要有一个点,然后你考虑一个贪心,就做完了。
* [arc116 F]
先考虑只有一个序列的情况。
首先并不一定每个人都从两个选项之中贪心选较劣的一个,举例子就是 1 4 3 2。
我们把它可视化一下。相当于在一个 \(n\times n\) 的下三角棋盘上,初始 \((1,n)\) 有一个棋子,两人轮流向右或下移动,最后停在哪个位置就是哪个数。
考虑把值域给去掉。本质上相当于有一个可接受集合 \(S\),A 的目标就是到达 \(S\),B 就是阻止这事件发生。
然后我们打个表,发现如果 \(n\) 是偶数,那么只要包含最中间两个之一,就可以接受;如果是奇数,需要同时包含中间和左右之一,就可以接受。
换句话说,如果是偶数,那么答案就是最中间两个取 max,如果是奇数,那么就是最中间的取 min 再取 max。
下一个想法就是怎么把一堆东西合并到一块去。可以考虑使用 sg 函数,这就要求我们把之前的问题变成公平组合游戏。这是可以的,具体来说,我们只需要在合适终点往后加一个位置就可以了。
额不太行,你变成公平组合游戏的要求是两个人分奇偶轮流进行操作,但是一旦扩充到多个游戏同时进行的情况,就爆炸了。
阅读了 sol,感觉我很 nt。
我这里觉得没办法做下去的原因是,一局游戏可能游玩方式是 AAABBAABBBAB 什么的,这东西非常难以考虑。
但是事实上,我们发现,偶长序列先手更优,奇长序列后手更优。所以,如果所有都是奇数,那先手取了一个之后后手肯定会跟上来一直让它成为较劣的情况。如果有偶数,那就会去争抢,抢完之后再继续。
其实我还是不太会证明这东西。
* [thupc2024 I]
为啥这么多人都会做我不会啊。
考虑两个星球什么时候相遇,发现是 \(\frac{xy}{|x-y|}\)。
拓展到更多星球怎么做。sol 里说你先考虑两个球相遇的所有可能位置,因为两球同时回归的周期是 \(lcm(x,y)\),所以可能位置是 \(\dfrac{lcm(x,y)}{\dfrac{xy}{|x-y|}}=\dfrac{|x-y|}{\gcd(x,y)}\)。
这下可以拓展到更多球了,我们以三个为例
这是为什么呢?
另一方面,我用了比较复杂的方法证另一边。先记 \(d=\gcd(x,y,z),x=dx',y=dy',z=dz'\)
再记 \(q=\gcd(x',y'),x'=qa,y'=qb\),
而 \((q,qb-z')=(q,z')\),因为 \((x',y',z')=1\),所以 \(((x',y'),z')=1\) 也就是 \((q,z')=1\)。那么 \((q|a-b|,|qb-z'|)=(|a-b|,|qb-z'|)\),所以这个是整数,我们就证完了。
然后你去处理一些细节最后做个容斥就行了。
* [thupc2024 E]
首先,为了简化问题,我们先 \(O(n)\) 枚举 \(d\),然后考虑求出一个数组 \(dp_x\) 表示一个 \(x\) 最多能转化出多少个 \(d\)。
这种可能带环的 dp,通常有一个考虑方法是说,类似于 SPFA,我们用一个队列记录当前需要进行更新的点。
考虑不出 INF 的情况下,\(dp\) 最大是多少。你发现很容易构造出一个 \(O(n^2)\) 的答案来,并且如果顺序实现不好的话,确实需要进行 \(O(n^2)\) 次更新。
考虑什么情况下会出 INF,显然如果 \(dp_x=\infty\),肯定是有个“环”,你考虑额外记录 \(cnt_x\) 表示从此出发最长的到 \(d\) 的一条路到底用了多少次操作,显然如果这个操作次数 \(>m\),那至少有一个操作被用了 \(2\) 次,那就说明你找到了一条环路,就爆炸了。
但是这个东西有问题,你可以考虑一个全都只能一换一的环,虽然这是个环路,但是并不会爆炸。如果我们加一个限制,\(cnt_x\) 它以 \(d\) 的数量为第一关键字,以长度为第二关键字排序,这样就不会无缘无故走环路了,也就是说走环路一定说明环路比直接走好,那就是真的爆了。
所以,每个点至多被更新 \(m\) 次,每次成功更新会引起 \(O(m)\) 次更新,简单分析复杂度大概是 \(O(n^2m^2)\)。
阅读了 sol,是另一个思考角度的思路。
[CF1976 D]
我会做了,但是是一个比较麻烦的做法,需要写一些复杂的东西。
唉算了说一下吧。
你考虑把 \([l,r]\) 合法的条件硬用前缀和 \(\ge 0\) 写出来,首先这要求 \(s_n=2(s_r-s_{l-1})\) 也就是说 \(2s_{l-1}=2s_r-s_n\)。
然后,我们分三段要求前缀和 \(\ge 0\),这要求 \(l\le pos\),其中 \(pos\) 是第一个 \(s_{pos}<0\) 的位置。以及 \(s_{l-1}+mn'(l,r)\ge 0\) 也就是说 \(s_{l-1}-mx(l,r)\ge 0\),记 \(p=\argmax_{x=l}^r s_x\),那就是要求 \(2s_{l-1}\ge s_p\)。以及 \(2s_{l-1}-s_r+mn(r+1,n)\ge 0\),记 \(p=\argmin_{x=r+1}^n s_x\),那就要求 \(2s_{l-1}\ge s_r-s_p\)。注意到一旦 \(r\) 确定了,那么 \(s_l\) 其实也确定了,所以本质上是一个 \(l\le pos,2s_l=2s_r-s_n\) 以及一个对 \(s_p\) 的限制。对 \(s_p\) 的限制可以转化为对 \(l\) 的区间限制,这样就转化为了数点问题,就做完了。
我肯定写麻烦了。
~ [CF1976 F]
仔细想想。
首先我们都知道,如果存在一条你加的边,把树边给覆盖了,那么这个树边就不再是桥,目标变成了用一些额外边去覆盖所有的边。
其次题目里有很奇怪的限制,一个是根只有一个儿子,另一个是要求非桥必须是与根连通的一个连通块。
首先因为这两个要求,你 \(k=1\) 的时候一定是连了一个根->最深儿子的边。
我们考虑设计 \(dp_{u,k}\) 表示 \(u\) 子树内使用了 \(k\) 次操作的结果。注意到由于特殊要求,我们 \(u\) 子树内必须至少存在一个从 \(u\) 开始的链,这样才能覆盖 \((u,fa)\) 这个边。而且,如果有多于 \(3\) 个链的话,我们可以在此处就进行合并以减少操作次数,所以每个子树只会向上传 \(1/2\) 条链。
考虑记 \(dp_{u,k,1/2}\) 为状态,转移的
偷瞄了一眼 jiangly 的代码,发现了不对劲的地方。
我们进行一个大胆地猜,就是说,你操作 \(k\) 次就一定能覆盖选 \(2k-1\) 个叶子到根的路径。显然我们最好能做到这个,接下来只需要构造一个方案就行了。
很简单,你考虑所有人的 lca,它的若干个子树一定是有奇数个奇数,然后让它们尽量匹配,最后剩下的不能匹配的,一定是某一个子树中的奇数,递归下去就行了。
所以,问题转化成选出来 \(2k-1\) 个叶子,使得它们到根的路径覆盖尽可能多的边。这个也是经典贪心,我们每次都选长链就行了。
其实这个早该发现了,之前发现它好像能够增量构造。

浙公网安备 33010602011771号