[ICPC 2026 Xi'an Invitational] 题解
A. North and South
简单题。
先考虑差分,设 \(d_i=a_i-a_{i-1}\),原操作相当于给 \(\{d_i\}\) 中间的位置 \(\pm 2\),两边的位置 \(\pm 1\),使得最终的 \(d_i=0\)。
但这样不太好维护,注意到选取的 \([l,r]\) 长度为偶数,那么每次操作后会有 \(\frac{r-l+1}2\) 个位置 \(-1\),\(\frac{r-l+1}2\) 个位置 \(+1\),从而操作完之后整个 \(a_i\) 的和是不变的。考虑到最终所有数相等,那么 \(\frac{\sum a_i}n \notin \Z\) 就直接无解。
设最终要变成的数为 \(x\),维护当前 \(a_i\) 和 \(x\) 的距离 \(b_i=a_i-x\),\(c_i=(-1)^{i-1}b_i\),此时操作就等价于给 \([l,r]\) 内的 \(c_i\) 同时加上 \(\pm 1\),此时考虑差分,记 \(d_i=c_i-c_{i-1}\),把区间加 \(s\) 转化成 \(d_l \gets d_l+s\) 和 \(d_{r+1} \gets d_{r+1}-s\),而 \(r-l+1\) 为偶数,则 \(r+1\) 和 \(l\) 的奇偶性相同,类比于在奇偶内转移偏移的一个操作,让 \(c_i=0\) 等价于 \(d_i=0\),那么“转移”的最小操作操作次数为 \(\sum_{i=1}^n \max(d_i,0)\),直接按照上面的统计是 \(\mathcal O(n)\) 的。
B. Operating Robot
能不能把题面写的像人话一点。
首先 \((0,0)\) 到 \((x,y)\) 总步数固定为 \(x+y\),因为步数方案是循环的,设 \(x+y=qn+r\),即执行了 \(q\) 轮完整的指令再执行前 \(r\) 个指令,则必须有 \(\xi=qs+t=x-qc_0-r_0\),其中 \(s\) 和 \(t\) 分别为所有 \(2\) 变 \(0\) 的个数和前 \(r\) 个中 \(2\) 变 \(0\) 的个数,\(c_0\) 为原串中 \(0\) 的个数,\(r_0\) 为前 \(r\) 为 \(0\) 的个数,下文中 \(c_1,c_2,r_1,r_2\) 同理。
考虑取
若 \(R<L\) 则直接无解,否则取 \(s=L,t=\xi-qs\),上述 \(q>0\)。
对于 \(q=0\) 的情况,取 \(s=\min(c_2,c_2-r_2+\xi),t=\xi\) 即可。
按照如上遍历原串去构造是 \(\mathcal O(n)\) 的。
补充一下上面 \(L\) 和 \(R\) 是怎么取出的:
对于下界 \(L\):
- 由于 \(t \le r_2\),即 \(\xi-qs \le r_2\),从而 \(qs \ge \xi-r_2\),得到第一个下界 \(\left \lceil \frac{\xi-r_2}q \right \rceil\)。
- 由于 \(t \le s\),即 \(\xi-qs \le s\),从而 \((q+1)s \ge \xi\),得到第二个下界 \(\left \lceil \frac \xi{q+1} \right \rceil\)。
那么下界就是这两个约束对 \(0\) 取 \(\max\)。
对于上界 \(R\):
- 由于 \(t \ge 0\),即 \(\xi-qs \ge 0\),从而 \(qs \le \xi\),得到第一个上界 \(\left \lfloor \frac \xi q \right \rfloor\)。
- 由于 \(s-t \le c_2-r_2\),即 \(s-\xi+qs \le c_2-r_2\),从而 \((q+1)s \le \xi+c_2-r_2\),得到第二个上界 \(\left \lfloor \frac{\xi+c_2-r_2}{q+1} \right \rfloor\)。
那么下界就是这两个约束取 \(\min\)。
C. Palindromic and Balanced
简单 DP。
设 \(f_{l,r}\) 表示 \([l,r]\) 内的最长合法串,根据题目中的定义,一个串 \(s\) 是回文平衡括号串必有 \(s_1=\texttt{(}\) 且 \(s_k=\texttt{)}\)。
这样不太好转移,考虑设 \(g_{l,r}\) 表示 \([l,r]\) 内左右括号数量相等的最长回文串长度以辅助 \(f_{l,r}\) 的转移。对于 \(g_{l,r}\),设当前要扩展的字符串为 \(s\):
- 如果两端都是 \(\texttt{(}\),那么可以扩展成 \(\texttt{()}s\texttt{)(}\)。
- 如果两端都是 \(\texttt{)}\),那么可以扩展成 \(\texttt{)(}s\texttt{()}\)。
对于 \(f_{l,r}\),若两端由 \(\texttt{()}\) 包裹,那么可以转移成 \(\texttt{(}\) 拼上某 \(g\) 再拼上 \(\texttt{)}\)。
直接做是 \(\mathcal O(n^4)\) 的,通过预处理左右的第一个 \(\texttt{(}\) 和 \(\texttt{)}\) 可以做到 \(\mathcal O(n^2)\)。
D. Qenerals
签子。
首先先占领 \(a_i\) 较小的地方肯定是不劣的,于是我们可以按照 \(a_i\) 先排个序。
考虑如何最大化占领的每一个堡垒的贡献,对于当前时间为 \(t\) 时遍历到的堡垒 \(i\),他所产生的贡献是 \(m-t\),那么如果他所耗费的士兵大于他的贡献肯定是不优的,即 \(a_i \le m-t\) 我们才会去占领这个堡垒,然而 \(a_i\) 此时是单调不减的,如果当前的不优,那么后面的一定不优,此时直接结束就可以了。
对于如何维护这个占领时间 \(t\),如果当前士兵不够占领这个堡垒需要等待 \(\left \lceil \frac{a_i-x}y \right \rceil\),否则直接同时占领即可。
如上直接做是 \(\mathcal O(n \log n)\) 的。
E. Registration
签子。
开个桶记录第 \(x\) 秒报名的人数,直接扫着判断即可,是 \(\mathcal O(n)\) 的。
注意到 \(v_i \le 10^9\),可以用 std::map 实现桶。
F. Split Sticks
类似于 A,注意到所有木棍的长度综合不变,不妨记为 \(s\),那么当且仅当 \(n_0 \mid s\) 时才有解,其中 \(n_0\) 是最终剩下的木棍数量。然而木棍数量是不会减少的,故 \(n_0 \le n\),结合 \(s=\sum a_i \le 10^{12}\),那么这样的 \(n_0<n\) 其实是不多的,可以直接枚举所有合法的 \(n_0\) 计算答案。
考虑模拟计算答案的过程。设 \(r=\frac sn\),对于当前长度为 \(x\) 的木棍,若 \(x>r\),考虑到最终需要所有木棍长度均为 \(r\),从而可以将 \(x\) 分成 \(r\) 和 \(x-r\),此时 \(x-r \le r\) 才可能有解;若 \(x<r\),从右边偷一点长度过来即可。
这样复杂度应该是 \(\mathcal O(n \tau(s))\) 的,需要优化。
我们注意到上面有一个有解的条件,即 \(r \ge \frac x2\),那么如果对于最大的 \(x\),即 \(x=\max a_i\),仍有 \(r<\frac x2\),则可以直接无解。然而这样做完复杂度是不变的,因为良心出题人可以给你一个全部都满足该条件的数据。
考虑减少一些冗余的枚举,发现不是所有合法的 \(n_0\) 在当前状态下都是对答案有贡献的,所以如果当前的 \(n-n_0 \ge ans\),那么这个 \(n_0\) 就没有必要去枚举了,而且如果我们倒序枚举的话可以直接 break。这样优化完应该是近似 \(\mathcal O(n)\) 的,带着一个应该 \(\le 10\) 的常数跑得飞快。
G. Transform
论出题人对 \(\operatorname{mex}\) 的热爱。
首先 \(\ge k\) 的数不用管,一次 \(\operatorname{mex}\) 就可以全删了,甚至这次 \(\operatorname{mex}\) 在最后做都是可以的,那么构造出 \(k\) 只需要构造出 \([0,k-1]\) 然后给他整体做一次 \(\operatorname{mex}\) 就行了。
对于构造出 \([0,k-1]\) 的过程,貌似是一个递推状物,相应地,设 \(f_i\) 表示需要有多少次对 \([0,i-1]\) 做 \(\operatorname{mex}\) 的过程,辅助地,设最开始 \(i\) 在 \(S\) 中的出现次数为 \(a_i\),当前构造出最终目标需要 \(c_i\) 个 \(i\)。
注意到若 \(j>i\),则每做一次对 \([0,j-1]\) 做 \(\operatorname{mex}\) 的过程都会消耗一个 \(i\),从而我们需要的 \(i\) 的个数最少就是消耗的个数,从而应有 \(c_i=\sum_{j=i+1}^k f_i\)。此时由于我们需要让操作次数尽量的小,且必须满足 \(c_i\),从而取 \(f_i=\max(0,c_i-a_i)\) 一定是不劣且最小的,因为必须要有 \(a_i+f_i \ge c_i\),然后把 \(c_{i-1} \gets c_i+f_i\) 一直递推下去即可。然而我们注意到最终需要 \(\sum_{i=1}^k f_i=c_1\) 次操作,所以我们只关心 \(c_i\) 的值,所以直接把递推式写成 \(c_{i-1} \gets c_i+\max(0,c_i-a_i)\) 即可。
最后考虑一些 corner case 的情况,首先 \(S=\{k\}\) 答案肯定是 \(0\),对 \(k=0\) 的情况如果原集合里没有 \(0\) 答案为 \(1\),否则为 \(2\),因为此时我们需要对于所有数进行一次 \(\operatorname{mex}\),然后再对剩下的一个数 \(\operatorname{mex}\) 成 \(0\)。还有一种可能就是 \(\sum_{i=1}^k f_i=0\),则原集合已经包括了 \([0,k-1]\),此时如果原集合有 \(k\) 的话答案要 \(+1\)。

浙公网安备 33010602011771号