ARC218

AtCoder Regular Contest 218

闲话

\(\text{Perf. } \color{red}{2926}\),再创新高了,以前真的想都不敢想。

感觉 \(11\) 月底和现在唯一的区别就是我清晰地意识到自己是个低水平选手,从而有更多的时间和勇气去做各种神秘的尝试,其实我一直做不明白传统题,与其说是一步一步推出来不如说是依靠额外的观察将一些求解方面的问题转化为判定相关的问题,从而极大程度缩短 提取结构 \(\to\) 解决问题 的思维链条。这才是早期我正赛能区分别人的东西,没想到中间弄丢了。还有就是精神状态好些了,至少能正常感知到时间。

一开始本来卡 B 题的 corner,以为要废,但后面发现 C 是比较 typical 的置换环上分析冒泡排序过程,E 是神秘观察题并成功对上脑电波,于是翻回来了。

其实这场也反映出很多缺陷。D 的倍增思路和 CF1738G 所刻画的结构本质是类似的,然后今天遇到了还是没写出来,这类结构我刻画的还是不够清楚,每个题各有自己的不清楚,回去要在补题的过程中想明白自己到底哪里的问题。


A (组合数学、*1400):

显然可以拆每个取值对应的贡献。令 \(v\) 在 \(P_i\) 中出现次数为 \(C_{v,i}\),那么可以容斥,考虑 \(v\) 不出现的方案数,此时有 \(m - C_{v,i}\) 种选法,总数减掉这个数就是 \(v\) 至少出现一次的方案数。则有答案 \(S = \sum\limits_{1 \le v \le nm} \left[ m^n - \prod\limits_{1 \le i \le n} \left (m - C_{v,i} \right) \right]\)。

时间复杂度 \(\mathcal{O}(nm)\)。

ac link


B (博弈论、Ad-hoc、分类讨论、*1700):

可以考虑直接顺着操作,将 \(a\) 升序排序,因为两种操作对相邻元素的差值没有影响所以必定可以这么做,消除的顺序也必定是 \(a_1,a_2,\dots,a_n\)。

考虑一个极长的连续段 \(a_l = a_{l+1} = \dots = a_r\),那么此时我要根据 \(a_{[r+1,n]}\) 的子问题是哪一侧必胜,尽可能通过消除 \(a_{[l,r]}\) 的过程让自己最终变为这一侧。

令 \(d = r - l + 1, x = a_l\),且 \(a_{[l,n]}\) 的子问题先手为 A,分类讨论 \(a_{[r+1,n]}\) 的先手是谁:

  • \(x = 0\):

    • 若 \(d = 1\) 那么先手只能是 B,这个是显然的;
    • 若 \(d \gt 1\) 那么 A 可以选择一次性消掉所有 \(a_i = x\),则先手变为 B,同样它也可以选择剩下恰好一个 \(a_i = 0\),从而做到先后手互换。
  • \(x = 1\):

    • 若 \(d = 1\) 那么同理先手只能是 A;
    • 若 \(d \gt 1\) 那么 A 只能将这一整段都变为 \(0\),此时变回 \((x = 0, d \gt 1)\) 的情形,那么 B 可以任意控制先后手了。
  • \(x \gt 1\):

    • 若 \(d = 1\) 那么 A 可以将 \(a_i\) 削减到 \(0/1\),所以可以直接控制先后手。
    • 若 \(d \gt 1\) 那么 A 将 \(a_i\) 削减到 \(1\),B 此时正在面对 \((x = 1, d \gt 1)\) 的局面,他只能将其转化为 \((x = 0, d \gt 1)\) 局面,此时 A 必定可以控制先后手。

最后一段的胜负关系可以直接依题意模拟出来,第 \(i\) 段想要成为先手/后手取决于第 \(i + 1\) 段是先手还是后手胜,这样从后往前递推即可。

时间复杂度 \(\mathcal{O}(n \log n)\),瓶颈在于排序。可能要考虑一些类似于全 \(0\) 序列,\(n = 1\) 序列这种很阴的东西,赛时记得写 gen 和 \(\mathcal{O}(n!)\) 代码对拍。

ac link


C (构造、Ad-hoc、*2000):

抛开这玩意是原,题本身还是挺好的。

有些大哥一眼看出 \(m = 2\) 可以直接冒泡排序,怎么一眼的我就不知道了。

首先 \(m = 1\) 必定不行。当 \(m = 1\) 时可以直接将排列分解为若干置换环,但你只能操作基于你给出那个置换的,每个环内的循环移位,这显然做不到任意重排,也就肯定做不到对任意序列排序。我构造两个位于不同环内的逆序对他就必定操作不了。

其次 \(m = 2\) 必定可行,可以用一个排列让环保持首尾相接的形态,另一个排列专门用来邻项交换,那么必定可以将交换位置旋转到环内目标位置前,这样可以直接冒泡排序,操作次数至多是 \(2n^2\)。

说人话就是两个置换分别用来操作 \(\text{swap}(1,2)\) 和 环上循环移位一格。这样直接构造出了可以遍历到环上每一个位置的等价操作,那么它必定可以实现任意的邻项交换且 \(1\) 次这种复合操作可以做到完全对应 \(1\) 次邻项交换,这时候直接冒泡排序即可,时间复杂度 \(\mathcal{O}(n^2)\)。

其实本质上 \(m = 1\) 不行是因为你冒泡排序是基于循环群的算子,而 \(\ge 3\) 的置换群必定不是循环群,那么你造一个可以分解置换群至 \(\lt 3\) 的算子结合上去就必定是对的,又因为只要构造出单位元就可以拆环了所以更没有用 \(m \geq 3\) 来拆环的道理(感觉不像人话)。

ac link


D (倍增、贪心、*2600):

题目所求即为区间 \([l,r]\) 中,使得满足 \(p_{i} \lt p_{i+1}\) 这样的位置数量最大的,最短子序列。

首先考虑全局查询,类似于 Dilworth 定理的思路,将序列划分为若干极长下降段,记段的数量为 \(k\),那么答案必定不超过 \(k - 1\)。因为每段内不可能出现上面所求的位置,而两端之间可能出一个这样的位置,所以答案至多为 \(k - 1\)。

然后我们构造地证明 \(k - 1\) 必定能取到。

对于第一段,选其中最小值必定是最优的,对第 \(i = 2, 3, \dots, k\) 段,我们发现如果第 \(i\) 段取任何值都无法与第 \(i - 1\) 段选取结果接上,那么:

  • 如果第 \(i - 1\) 段选的值大于第 \(i\) 段的最大值,那么必须要在第 \(i - 1\) 段中多加一个数来确保答案取到 \(k - 1\)。可以选择第 \(i - 1\) 段最小值插在第 \(i - 1\) 段所选数后面,如果这样还不行代表第 \(i - 1\) 段最小值大于第 \(i\) 段最大值,那么应当合并为一段,矛盾了。

  • 如果第 \(i - 1\) 段选的值小于等于第 \(i\) 段最大值,记两个数分别为 \(L,R\),那么 \((L,R]\) 内的数都是可选的,这样必定可以使答案加上第 \(i\) 段的贡献,这样传递下去可以归纳证明最终取到 \(k - 1\)。

由此我们看出,对于任意一个元素 \(a_i\),他要跳到哪里是固定的,不会随着区间变化而变化(只会因为越界被框住),所以考虑先按照上面策略 \(\mathcal{O}(n)\) 模拟出每个数跳一次去哪里,然后预处理倍增数组,每次询问直接倍增回答查询即可做到 \(\mathcal{O}(q \log n)\)。

总时间复杂度 \(\mathcal{O}\big((n + q) \log n\big)\)。

ac link


E (组合数学、树状数组、Ad-hoc、*2700):

原问题给定的操作太复杂了,不好刻画。需要找到等效的操作。

容易模拟样例发现这个操作可以等价为先翻转整个序列再循环右移 \(i\) 位,这等价于先循环右移 \(n - i\) 位再翻转整个序列。那么一次操作的本质就是翻转整个环的同时,换一个空隙断开这个环。考虑整个 \(k\) 次操作过程,对于第二次操作,可以将其从 \((\text{rev}, \text{rot}(i))\) 变为 \((\text{rot}(n - i), \text{rev})\),此时相邻两次循环移位操作可以直接合并,这告诉我们可以将所有翻转操作提到最后面,因此可以将执行 \(k\) 次操作理解为,先进行 \(k\) 次循环移位操作,再将序列翻转 \(k\) 次。由此我们发现只有 \(k\) 的奇偶性会影响序列最终的方向。

对于最终序列上任意一个逆序对 \((a_i,a_j)\),假设对应的原序列下标为 \(p_i,p_j\),那么如果不考虑环的翻转,有 \(p_i - p_j + n \times [p_i \lt p_j]\) 种端点可以将 \((a_i,a_j)\) 算作一个逆序对。其实就是不能在他俩中间断开,这样就可以保证维持偏序的子区间在最终序列上是连续的一段。

此时根据上面拆的贡献,我们知道如果不考虑翻转,每个断点处逆序对之和为 \(\sum_{a_i \gt a_j} p_i - p_j + n \times [p_i \lt p_j] = n \times I_0 + \sum_{1 \le i \le n} p_i \times (2i - n - 1)\),将其记作 \(S_0\),其中 \(I_0\) 就是初始逆序对数目。

此时归纳可证,在第 \(k\) 次操作之后,断点仍为下标 \(1\) 前面空隙的概率为可解的 \(X\),其余位置均为 \(X - (-1)^k\)。求和后显然有 \(nX - (n - 1)(-1)^k = (n - 1)^k\),那么容易解出 \(X\) 的值。

设初始逆序对数目为 \(I_0\),不考虑翻转此时所有情形的逆序对数量之和为 \([X - (-1)^k] \times S_0 + I_0 \times (-1)^k\)。最终再将翻转的可能贡献补上(如果是奇数次翻转就将答案换为它的补集)。

整个过程只需要值域树状数组来解决,时间复杂度 \(\mathcal{O}(n \log n)\)。

ac link


posted @ 2026-09-28 00:43  Twistedmind  阅读(2)  评论(0)    收藏  举报