1689
E. ANDfinity
给出 个非负整数 , 与 连边当且仅当 ,这里的 是位与运算。
一次,你可以执行两种操作的一种:
选择一个 ,让其 。
选择一个为正的 ,让其 。
求让整个图连通,所需要的最少操作数。
。
Hint1
首先,将 的位置加上 。
注意到任意两个奇数都连通。
Hint2
考虑偶数,对偶数减一性质比较良好:这样会在 之后的位都产生 ,且它就和奇数连起来了。
Hint3
试说明:此时 。
Solution
挺有意思的题,vp被前面的题搞心态差了一点时间...
注意到若连通,则不会有 存在。因此对于所有 的位置先加一,这样全部为正整数。
考虑奇数之间由于最低位置存在 必定连通;对于偶数,我们发现,当它加上 或减 以后,也会和奇数连通。
偶数的 是好考虑的,而减一,就是找到 并置零,将所有更低的位置为 。
所以如果减一,我们有个想法是找到 最大的偶数排序,这样就能顺带把 更小的位置连上。
但是如果有多个 最大的这样就寄了。
然后发现如果还有 最大的,把它 ,这样就满足条件了。
所以关键结论是此时的 ,因此我们只要检查是否能让 即可。
首先我们发现可以 的去检查一个数组是否合法,所以暴力枚举修改的哪个位置,就可以 地做了。
P.S. 这题和 CF1553G 都一样,只要看出 就随便做了。
1693
C. Keshi in Search of AmShZ
给出一张 点 边有向图,可能有重边。初始,角色在点 ,目标是走到点 。
每天,可以执行下面两种操作的一种,直到角色走到 为止:
-
选择任意一条边,删去。
-
假设角色在点 ,此时随机游走到一个点 ,满足 有一条未被删的连边。
问最坏情况下,从 最少需要多少天。
。
Hint1
倒着设计 dp!Hint2
观察到未确定的 dp 值里,最小的永远不会再被更新。考虑类 dij 的方式确定 dp。
Solution
-
图论是大弱项
-
从一开始我的思考方式就出现了问题
设 是从点 开始,最少需要多少天才能到达点 。显然 即为所求。
考虑转移,,其中 应该是一个最糟糕的点。换言之如果 和 有连边,且 ,则要么我们删去 的连边,否则在最坏情况下我们必须从 走到 而不是从 走到 。
所以 ,其中 是所有 能一步走到的点 中, 的。
注意到这个图并不是 ,所以不能直接转移 dp。
图上 dp 的另一种实现是最短路。
因为 所以这个 dp 的转移是单调不减的,换言之我们可以用类 dijkstra 的方法去迭代求 :当前最小的,未被标记的 一定不会变得更小了,所以取出 并且标记,然后去进行对 的转移。
时间复杂度 。
P.S. 很多时候图论问题都应该是设计一个“当前位置到终点的最短路”而不是“起始位置到当前位置的最短路”。一个典型的例子就是绝大部分期望 的状态设计(这类期望 本质上也是一个 游走问题)。
在本题,为何我们不能设 代表 最坏情况下的最少天数?因为如果 ,我们并不能保证, 就会比 来得更差(比如若 无法走到 ,那 反而会更优秀)。而倒着设计显然不会出现此类问题。
这道题虽然简单,但是很有思考价值。
D. Decinc Dividing
若一个序列能恰好拆成一个上升子序列和一个下降子序列(可空),则称其为好的。
给出一个 排列 ,询问 的好的子段的个数。
。
非常牛逼的一道题啊。
首先本题的 check 已经是众所周知的一道题了:CF1144G。
事实上关于序列(排列)拆分成一个上升子序列和一个下降子序列,最简便的方法也是 dp:设 是 ,其中第 个元素放入了上升子序列,此时下降子序列结尾的最大值;以及 表示第 个元素放入了下降子序列,此时上升子序列结尾的最小值。这样有一个 的 dp 去实现 check。
在本题中,设 与 代表从 位置开始,然后第 个放入了上升/下降子序列,此时对应序列结尾的最优秀值。如果 说明此时下降序列可空,如果 则说明不能把 放进上升子序列。显然 合法当且仅当 以及 不同时成立。
结论:如果 确定,则 只有 种可能取值。且随着 的上升而上升。
证明:首先 和 是肯定存在的。然后假设存在一个最大的 使得 ,则首先 和 必定有至少一个划分进下降子序列。且 。要么 划分进了下降子序列且 划分进了上升子序列,那么我们显然可以把 全部划分入上升子序列;或者 划分进了下降子序列,此时 必须划分进上升子序列,由此剩余的也肯定可以划分进上升子序列。
显然对于 有类似结论。
所以我们降序(或者升序)枚举 皆可,然后暴力从 更新到 ,如果更新前后的 没有任何变化,我们就停止更新。
这样,每进行一次更新,意味着至少一个 或者 发生了变化,而总变化次数是 级别的。因此时间复杂度同样是 。
E. Outermost Maximums
有一个长度为 的序列 ,其中 已确定。现在给你 的值。
你可以执行任意多次两种操作的一种,使得 都变为 :
-
找到 最左边的最大值位置 ,并令 。
-
找到 最右边的最大值位置 ,并令 。
试找出最少操作步数,。
首先我们肯定会不断操作最大值并让其变为更小的值。
所以假设初始最大值位置为 。显然 的一段前缀是用操作 ,剩下的一部分后缀是用操作 。
设 表示 左边最大的 的位置,同理有 。那么 单调上升, 单调下降。
所以我们可以保证一轮变化后 变成了 。显然这是最优秀的。
容易发现按照这样的变化方式,实际上每个位置是独立的。换言之,我们把问题改写成,给出一个和 完全一致的序列 ,然后枚举 从 。每次令 且重新更新 直到 为止。问变化次数和。
到这里暴力模拟是可以做到 级别的,仍然不够优秀。下面是神来之笔:
我们研究某个时刻的 :考虑值域。设 当且仅当有一个 满足 ,同理 当且仅当有一个 满足 。
然后,我们初始在 位置,然后不断向前走,每次走到最近的 或 的位置(显然我们会走比较远的那个,但是在这里没有什么用),直到走到 位置。
设 是从 外面进入,走出 的最少步数。两个 分别代表我们进来的时候是想走到 还是 ,以及出去的时候是想走到 还是 。
容易发现这个 是容易 合并的。而 增加的过程就是修改了 ,每次求的是 。所以用线段树维护这个结构就行了。
虽然说起来简单,但这个做法非常的高妙,非常的有启发意义。
时间复杂度 。
P.S. 这题没有独立想到最后的 DS 优化部分,思考了一下,发现这部分和之前做过的一道 CF 题 MCMF(当时也是想到 没有得出进一步的 DS 优化)存在一类共同点:
就是我们要对数列的每个位置都去执行一个类似的操作并求结果,而这个操作是依赖于数列本身的。那这个时候我们发现单个的考虑其实往往没有什么优秀性质,但我们可以用一些 DS 去维护,为什么可以 DS,是因为 的时候,由于你的答案只依赖于数列本身,而指针移动一位造成的变化往往很小。所以我们可以很快地处理这些变化,然后就变成一些简单的 DS 了。
1695
D2. Tree Queries(Hard Version)
给出一颗 点的树,找到最小的 ,满足:
存在一个点集 ,然后对于树上每个点 ,设 到这 个点的最短路数组为 。不存在两个点 使得 。
。
很牛逼的 div2 D。
显然若点集中有两点 ,则路径 上的所有点不用考虑,它们的最短路数组一定唯一。
所以假设点集已经确定,对于点集中任意两点 ,把路径 上的点全部染色,则答案合法等价于没有一个染色点有 个的未染色相邻节点。
所以容易想到设 代表子树 合法的最小代价,设 的所有儿子中有 个儿子的 (实际上这意味着 是一条链),则有:
但这其实是有问题的。原因在于假设 是二叉的,你只在一颗子树里找点加入点集是不够的,要么 子树外(或者 本身)还得来一个点,要么 要是三叉往上的,这样 点才会被染色到。
由此得出两种思路:
-
的时候必然有一个点被染色,暴力枚举它,作为树根,执行上面的 dp,然后 最后取 。直接暴力是 的(可以通过 D1),我们发现这个 dp 容易换根优化,时间复杂度 。
-
随便找一个三叉往上的点定根,然后跑一遍 dp 就行了。如果找不到,说明是个链。
1698
F. Equal Reversal
给出两个长度为 的序列 ,你需要在不超过 次操作内将 变为 。一次操作指选定一个区间 满足 并反转 。
。
神题。
首先假设在 之间连一条无向边,则不管怎么操作,这个图 不会发生改变。(本质上是相邻元素对集合不会改变)。
而我们从 这个点开始走,每次沿着 走,可以发现走出了 的一个欧拉路。
事实上 还有别的从 开始的欧拉路。显然一条欧拉路唯一对应了一个新的序列 ,可以证明的是每个 都可以由原序列 通过若干次反转得到。
我们先来研究反转在图论上的意义。反转确实不会更改图 的形态,但他会更改我们的欧拉路径。具体而言,是选择一个环,并且将定向取反,访问顺序也取反。即本来是 ,更改为 。
现在来证明运用这个操作,总能让两条 开始的欧拉路径重合。
我们采用归纳+反证的形式,即假设 与 处是第一处不同的地方(显然 )。设 。
由于走的都是欧拉路径,所以在 的走法里, 这条边还是要走的;在 的走法里, 这条边还是要走的。这实际上告诉我们这两条边都存在于环上。
-
假设在 的走法中,走的是 。此时 就是一个环。反转它,则先走 。
-
假设在 的走法中,走的是 。此时路径形态形如 。反转 在的那个环,则变成了 ,回到第一种情况。
所以两条欧拉路径始终能完成重合。
放到原序列,其实两种讨论,对应了构造的两种情况。首先,总的思路是,从前往后一位位构造。当第 位不同的时候,必定满足下面两种情况之一:
-
存在 且 ,此时直接翻转 即可。
-
存在 且 ,且存在某个区间 满足 ,,此时翻转 ,回到情况 1.
我们发现其实与图论上的两种情况完美契合。
时间复杂度 。操作数上界 。
G. Long Binary String
给出一个长度为 ,初始全为 的串 ,以及一个 串 。你可以执行任意次操作,每次把 放在 的任意位置并将相应位置异或 。问是否能让最后的 恰好有两个 ,若有,输出字典序最小的 中, 的两个位置。
。
这是多项式题是我没想到的...
首先忽略原串 的前导零,然后将其看成一个系数 的幂级数 。
然后我们类似的,对操作序列定义一个幂级数 ,当我们有一次操作, 的首位和第 位对齐了的时候,那么 。这样,我们得到的最后的串显然可以用 表示,这里我们需要重新改写多项式乘法,将其改为在异或意义下。(可以看成,就是常规的多项式乘法,最后把系数全部模 的一个过程。)
显然第一个位置一定是 ,而第二个为 的位置是不确定的,换言之有方程 ,其中 是一个正整数,我们希望它尽可能小。
注意到 是任意的,所以原式等价于同余方程 ,然后就是多项式版本的一个 bsgs 过程。因为你注意到这里 的上界就是 (考虑模 的剩余系大小)。
我们可以把系数压进一个 long long 来存。注意到乘法的时候会爆精度,所以乘法的时候用一个 __int128 缓冲即可。
时间复杂度 ,其中 。
1699
E. Three Days Grace
给出一个多重集 ,其中的元素都在 之间,你可以执行任意多次操作。每次操作选出多重集的一个元素 ,然后找到两个大于 的数 使得 ,最后删除 ,加入 。
问可能的, 的最小值。
。
考虑枚举最小值 ,然后设 是 拆分成若干 的数之积,且最大值的最小可能值。
首先考虑维护 ,发现在 移动的过程中,假设当前移动到了 ,那么显然只有 的倍数的 才会变化。
也就是说 的总计算次数是 的,但是每次重新计算 是花费 的时间的,显然不能通过,这比 实质上要慢很多。
如果我们是增大 ,那么是不好维护滴。注意到我们如果是降序枚举 ,那么 值只可能变得越来越小,所以我们每次更新 的时候,直接把 和原有的取 即可。
现在我们可以 的总时间维护所有 dp 值了。我们还需要知道, 的动态最大值。一个朴素的想法是维护一个多重集,每次修改 之前删了,修改后把新的 dp 值放进去。但这样复杂度就不能保证是 了。还是注意到 值永远在下降,此时有个套路,就是维护一个桶,维护一个指针表示当前最大值。如果桶里指针位置为空,那么之后的时刻这个位置不可能再放入数了(因为最大值永远在下降),此时直接让指针 知道指向的桶的位置非 即可。这样这个过程均摊下来是 的。于是总时间复杂度 ,空间复杂度 。
事实上枚举 有对称做法,但我们必须每次寻找约数,这是比较难实现的。另外,枚举 的做法并不会跑满,因为枚举 的时候, 才有意义,那就意味着 的时候才会发生 dp 的更新。
1700
E. Serega the Pirate
给出一个 的矩阵 ,满足 且两两不同。称矩阵 是合法的,当且仅当存在一条四联通路径,从 所在位置出发, 所在位置结束,且满足:对于任意 , 第一次出现晚于 第一次出现。
定义一次操作是交换 中的两个元素位置。
如果 是合法的,则输出 。如果 可以经过恰好一次操作变得合法,输出 后,再输出可能的操作种数。否则输出 。
。
首先这个合法就等价于每个非 位置都至少有一个相邻的小于它的位置。所以 是容易判的。我们称满足这样性质的位置为合法位置。
然后注意到一次交换最多让 个位置从不合法变为合法。所以我们在不合法位置大于 的时候直接输出 。
否则,交换的两个位置,必定有一个位置,它要么是不合法位置,要么与合法位置相邻。这样的位置最多有 个。
所以在 的时间内可以确定所有点对,带 的常数。 是 的,这里常数不能太大,因为本题的时间限制比较严格。
F. Puzzle
给出两个 的 矩阵 。定义一次操作是交换 中相邻两个位置的值。问把 变为 的最小操作数,或报告无解。
。
很精妙的题,有 atc 的感觉。
首先无解的条件就是 中 的个数不相等。我们接下来探讨有解的情况。
因为一次操作必定牵扯到一个 ,所以我们可以这样更改题意:允许 在中途重叠,一次操作定义为选择一个 并移动。我们容易发现这个问题的答案和原问题是等价的。
这样有一个什么好处?就是说我们不用考虑 这种操作的麻烦了(从交换的角度来看,它是无意义的)。我们可以直接把原问题变成将 与 中的 进行一一匹配,边权为曼哈顿距离,求权最小的完美匹配。这个转化是特殊的,它只在 的矩阵上成立。
另一个角度是从 的情况入手。显然我们会把两个矩阵中的 排序,然后一一配对。事实上,这个策略有一个更形式化的表述:,其中 是 中 的前缀和, 同理。记 。
现在让我们把视角放到 的矩阵中。我们注意到根据先前的转化,所有的上下操作都可以放到开头完成。注意到一次上下交换的操作实质上是把一行的 全部减一,另外一行的 全部加一。
我们从前往后扫,注意到若两行 同号则执行上下交换不优;若异号,假设第一次出现,则此时绝对值较小的是 。我们把正的减去一,负的加上一,这样答案减小了一。同时我们发现按照这样的调整,此时变为了同号的情况。换言之按照这个贪心,每次碰到异号,绝对值较小的值一定是 。所以总能实现一次上下操作(如果不能实现,说明为 ,那值就不会变化,与“第一次”异号矛盾)。所以这个 的贪心就能解决问题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下