ARC228
AtCoder Regular Contest++ 228
闲话
有生之年!场切 *3500!
下午全力打 MX 所以脑子已经不是很好了,有想过要不要直接睡觉或者 CS 启动。想了想还是决定贪一波,万一呢。吃完晚饭瘫在床上蠕动并进入濒死判定,大概 19:40 的时候想起来冰箱里有宝物,爬起来灌了一瓶蓝牛,感觉,我还能蒸!看了榜,小w小e和夜鸣汉都在大不了一起掉分遂选择 rated,结果开赛看榜发现咋全都跑了。
10min 看了所有题,发现是五个排列题,三个排列计数,一个区间最值状物的最优化,一个神秘构造,吓哭了。
我选择开构造,立刻注意到因为合并多个排列的过程有交换律所以可以增量构造,按任意顺序只要无法合并 \(P_i\) 那么一定无解,调整法易证这个是充要的。也就是说可以对着增量构造的每一步条件取反从而找出所有无解条件。
进一步地,合并过程等价于找到每个排列对应的最小正交分量,求出他们在整周期 \(T = \text{lcm}\{l_1,l_2,\dots,l_k\}\) 里面的指数 \(e_i\) 然后构造这些分量对应的置换环的 \(\frac{T}{e_i}\) 次幂再复合到一起就可以给出答案排列。然后你注意到直接质因数分解因为环长互质就必定不会出现步长耦合的情形,再用类似于 exCRT 的东西合并若干个置换环。貌似是对的?然后你注意到这个是必要不是充分,想了一会发现因为同一个排列共用一个 \(k\) 所以检查同一个 \(k\) 在每个质因子意义下的 shift 不会撞就充分了。此时是 20:40,然后 AB 加起来不到 \(100\) 人过,我 Fav 榜里面没有通过题目超过一题的老哥,不是哥们?这是 AGC 吗?
但是我造了好多极端数据都叉不掉啊,这个框架极有可能是对的,那剩下就只有对拍能解决了。代码好难写,写了好久,主要是找环和判置换幂的部分细节巨多,而且他给的 \(n = 10\) 样例只有两个环说是,很多细节没法直接对着调出来。造了三个拍子,一个是 \(n \leq 5, m \leq 2\) 的全部排列对应的数据,第二、三个分别是用给定质数定向生成的有解数据,以及必定至少有一个排列无法通过幂判定的必定无解数据,细节好多调了好久,最后发现是线筛最小质因子的地方写成了下标,我管你那么多的直接改埃筛,哈气!
接下来大概有 35 分钟左右处于改一句拍一下然后再改的状态,大概是 21:10 左右通过了 \(10^3\) 组对拍,注意到此时 D 无人通过,吗的我管它呢,直接交一发!然后它就过了,直接一个中国人能飞有没有懂的,整个人都在发抖像磕了一样。此时 lmc 姐姐提醒我 A 是不可做题,可以直接看 B。斯哈斯哈,那就感谢了。
尝试了一下发现确实直接建出笛卡尔树后直接对区间限制贪心就好了,因为每次只会令 \(c_i\) 自增 \(1\) 而它又是固定的二次项所以增量就是形如 \(A_i \times (2k - 1)\) 状物,直接用 set 维护每个节点对应区间内元素的增量,启发式合并子节点对应的增量就能做到 \(\mathcal{O}(n \log^2 n)\),过的时候来到 rk4。
接下来我的脑子已经无法正常思考了,装模做样看 A,然后口胡的切入角度貌似是有问题的,题解是直接 0/1 化然后转化成 \(2 \times n\) 网格上的路径计数,我的理解是分三层点,\(1,3\) 层就是 \(p,q\) 下标然后 \(2\) 层是颜色(排列每个位置对应的取值),然后变成要消圈直到剩下若干个对位的三元链的结构,尝试套用 ARC207A 和 ARC162E 的二分图匹配 + 代价延迟计算 trick,到现在也不清楚能否修成等效的东西,根本想不明白罚坐到比赛结束。
赛后看榜发现过一题 perf 1600+,手速快或者多过一题 perf 直接上橙。其次就是 B 和 C 好像都是典题,被 GPT 老师爆了,什么叫一群 2200- 暴打 2500+,何意味呢?
B (贪心、启发式合并、*1600):
一脚踢飞。
考虑从每个点确定它的父节点位置。设 \(P_i\) 的父节点为 \(s_i\),那么找出 \(Q_i\) 表示 \(P_i\) 左侧最近的,权值大于 \(P_i\) 的位置,若不存在则取 \(1\),父节点的限制有且仅有 \(Q_i \leq s_i \lt P_i\)。换言之 \(P_i\) 的可选父节点区间即为 \([Q_i, i-1]\)。注意到这样的区间要么包含要么不交,由此可以直接按照笛卡尔树思路建树然后直接在树上贪心选点,对于位置 \(i\) 它的第 \(k\) 个子节点对答案产生的增量为 \(A_{P_i} \times (2k - 1)\),那么维护这个过程只需要支持:
- 合并两个小根堆
- 取当前最小值
- 取出最小值之后将 \(k \leftarrow k + 1\) 的代价放进堆中。
可以直接用线段树或 set 启发式合并解决。时间复杂度 \(\mathcal{O}(n \log n)\) 或 \(\mathcal{O}(n \log^2 n)\)。
C (组合数学、莫队、*2700):
有些变态。
首先肯定是对一个操作后固定的排列,确定逆序对的贡献从哪里来的。
对于 \(i, j \notin x\) 的情形,这部分逆序对是静态的,可以直接算。
又因为 \(i, j \in x\) 的时候整个子序列是升序排序的,所以不存在 \(i, j \in x\) 的逆序对。
所以只可能是 \(i,j\) 中恰有一个 \(x\) 内元素,所以可以枚举 \(i\) 钦定它没有被排序,然后看所有被排序的 \(x\) 能给 \(i\) 带来多少贡献。
如果 \(j \lt i\) 并且 \(j \in x\),那么产生逆序对当且仅当:
- \(P_j \gt P_i\) 并且对应 \(x\) 中 \(P_j\) 最终位置 \(j' \lt i\);
- \(P_j \lt P_i\) 并且对应 \(x\) 中 \(P_j\) 最终位置 \(j' \gt i\)。
所以你发现只需要考虑所有 \(j \lt i, P_j \gt P_i\) 的位置以及 \(j \gt i, P_j \lt P_i\) 的位置,记当前 \(x\) 内选中的两类下标数量分别为 \(c_1, c_0\) 那么这些一共会产生 \(|c_0 - c_1|\) 个逆序对。
所以只需要将整个序列对应的 \(c_0,c_1\) 求出来,枚举两侧选取数量就可以算出 \(i\) 对应的贡献 \(W_i = \sum_{x=0}^{c_0} \sum_{y=0}^{c_1} \binom{c_0}{x} \binom{c_1}{y} |x - y|\)。
然后你发现绝对值不好算可以直接拆开,变成统计对 \(x \geq y\) 部分的 \(\binom{c_0}{x} \binom{c_1}{y} (x - y)\) 以及相应 \(x \lt y\) 的对称的 \(y - x\) 两部分,这两个计算方式是一模一样的,以前者为例:注意到 \(c_0,c_1\) 只和 \(i\) 以及 \(P_i\) 有关,又因为排列的值域和长度同阶且无相同元素所以 \(i\) 的变化量与 \(P_i\) 的变化量以及 \(c_0,c_1\) 的变化量都是同阶的。考虑用类似于值域分层的角度去理解,扫描线移动 \(1\) 单位长度至多只会令原始计算的 \(\binom{c_0}{x}\) 变成 \(\binom{c_0 + 1}{x}\) 状物,换言之就是多了一层组合数。也就是
也就是只需要预处理出组合数,记录 \(\binom{c_0}{x} \binom{c_1}{y} (x - y)\) 以及 \(\binom{c_0}{x} \binom{c_1}{y}\) 就可以直接 \(\mathcal{O}(1)\) 更新出相邻 \(i,P_i\) 对应的答案。由此可以直接对 \((i,P_i)\) 用莫队维护,做到 \(\mathcal{O}(n \sqrt{n})\)。你注意到对右端点右移以及左端点左移的操作因为多一个要 long long 的乘法所以常数稍大一点,可以考虑块长那里稍微调一调,整体来讲是不卡常的,直接设 \(B = 300\) 就可以跑进 \(400 \ \text{ms}\)。
D (置换、数论、构造、Ad-hoc、*3500):
我已启动。
假设按照一个顺序,把 \(m\) 个排列一个个加进去并实时维护当前的答案 \(Q\),那么每次等价于判断是否存在一个新的排列 \(Q'\),使得旧的 \(Q\) 和当前新加的 \(P_i\) 均为 \(Q'\) 的幂。如果存在,因为之前所有排列本来就是 \(Q\) 的幂,而 \(Q\) 又是 \(Q'\) 的幂,所以之前所有排列以及当前的 \(P_i\) 均为 \(Q'\) 的幂。那么可以直接将答案换为 \(Q'\)。而如果某一步无法合并,但原问题实际存在答案 \(R\),因为之前维护的 \(Q\),也即每个处理过的 \(P_i\) 均为 \(R\) 的幂,所以 \(Q\) 也必定是 \(R\) 的幂,新加入的 \(P_i\) 也是 \(R\) 的幂。这就说明 \(Q,P_i\) 必然都来自于同一个 \(R\) 的幂操作,此时必定是可以合并的,那么这就与不可合并的假设以及存在一个 \(R\) 的假设矛盾了。由此,直接增量构造,只要原问题有解,最终必定能得出一组解。
现在我们解决两个排列是否能合并的问题。
你注意到,假设一个排列有环长 \(6,4\),另一个排列有环长 \(6,2\),如果直接找最小公倍数 \(12\) 然后强行构造一个长度为 \(12\) 的大环,因为 \(\gcd(6,4,2) = 2\) 所以他们有些步长会耦合在一起,奇数位置的信息就彻底损失掉了,根本没法直接构造。
由此,首先我们应当找到一种确保不会损失信息的表示排列的方式。设排列 \(P\) 的所有环长度为 \(l_1,l_2,\dots,l_k\),那么 \(P\) 的周期 \(T = \text{lcm}\{l_1,l_2,\dots,l_k\}\)。这使我们想到可以按质数去拆分,因为两两必定互质的特性他们的步长必定是不会耦合的,换言之这些东西能作为最小的正交分量表示出这个环对应的所有信息。对一个质数 \(x\),令其在 \(T\) 中对应的最高次指数为 \(\alpha_x\),因为我们需要“仅保留”和 \(x\) 有关的信息,所以考虑构造出 \(P_{x} = P^{T / x^{\alpha_x}}\)。此时它所有环的长度都是 \(x\) 的幂次,周期恰为 \(x^{\alpha_x}\),又因为上面说的互质的特性,虽然所有质数部分乘积不一定等于 \(P\),但它与 \(P\) 具有所有相同的幂次,所以可以视作同一个幂序列的生成序列来使用。因为本质上我们要判定的是,是否存在一个新的 \(Q'\),使得 \(Q = Q'^{x}\) 并且 \(P_i = Q'^{y}\) 然后令 \(Q \leftarrow Q'\),所以此时拆出不交的环之后这一步判定是容易的,因为两个排列在每个以 \(Q'\) 为基础的环上的操作都是正交的循环位移,所以任意两个符合条件的排列均满足 \(P_{Q_i} = Q_{P_i}\),这个是必要条件。
问题转化为合并两个排列的相同质数部分对应的信息。对每个质数 \(x\),我们分别得到 \(Q_x\) 和 \(P_{i,x}\)。假设其周期分别为 \(x^{\alpha}, x^{\beta}\),如果 \(\alpha \geq \beta\) 那么当后者是前者的一个幂时,他们可以直接用前者统一表示。反过来,如果他们都来自同一个排列 \(R\) 的幂,设 \(Q_x = R^{u}, P_{i,x} = R^{v}\),因为前者周期为更大的 \(x^{\alpha}\),其损失的 \(x\) 因子个数更少,而 \(P_{i,x}\) 周期更小,说明它的指数至少多含有 \(\alpha - \beta\) 个 \(x\) 因子,因此可以解出同余方程 \(u \times t \equiv v \pmod {x^{\gamma}}\),从而取 \(t\) 做幂次得到 \(P_{i,x} = Q_x^{t}\)。所以当 \(\alpha \geq \beta\) 时,两个部分能合并当且仅当 \(P_{i,x}\) 是 \(Q_x\) 的幂。对 \(\alpha \lt \beta\) 是完全对称的。
故此时问题转化为判断一个排列是另一个排列的幂,假设两个质数信息对应的排列为 \(X,Y\),已知 \(X\) 的周期为 \(d\)。那么因为所有环长均为该质数的幂,\(X\) 至少有一个长度为 \(d\) 的环,设为 \(\{u_0,u_1,u_2,\dots,u_{d-1}\}\),如果 \(Y = X^k\) 那么在这个环上必定有 \(Y(u_0) = u_k\),因为 \(Y(u_0)\) 的实际位置直接确定为 \(k \bmod d\)。然后你再代回去判断是否对每个位置都相符即可。这里需要比较整个排列,因为其他环上的位移也是由这同一个 \(k\) 决定的,那么此时充分条件也确定了。
那么此时我们已经能将所有相同质数部分合并到一起了,再考虑如何将不同质数合并到一起。考虑类似 CRT 的过程,假设对质数 \(x\) 我们合并出的答案为 \(T_{x}\),周期为 \(x^{k_{x}}\),对每个质数 \(x\),有 \(Q_x = T_{x}^{u_x}\),令 \(Q' = \prod_{x} T_x\),因为各个周期 \(x^{k_x}\) 两两互质所以必定存在 \(K\) 使得 \(K \equiv u_x \pmod{x^{k_x}}\),则有 \(Q = (Q')^K\),对 \(P_i\) 同理。
实现的时候,为了避免一些重复造轮子的工作,因为合并不同质数那个判定是对最后每个质数的结果来做,所以可以一开始直接分解第一个排列,然后每次合并新排列的时候只维护各个质数部分,最终合并到一起即可,这样会好写很多。
时间复杂度 \(\mathcal{O}(n^2m)\),如果预处理每个环长的质数乘积那么可以做到 \(\mathcal{O}(\pi(n) \times mn)\)。
浙公网安备 33010602011771号