ARC154
A - Swap Digit
题意:
有 \(2\) 个长为 \(n \le200000\) 位的正整数 \(A, B\),你可以任意交换 \(A, B\) 第 \(i\) 位的数字,求 \(A\times B\) 的最小值,对 \(998244353\) 取模。
思路:
将 \(A\) 表示为 \(\sum_{i=0}^{n-1}10^i a_i\),\(B\) 同理。
那么我们有:
对于 \(a_ib_i\) 部分,是始终不变的,因此我们只需要考虑 \(a_ib_j+a_jb_i\) 的部分。
若 \(a_i<b_i\),那么我们令 \(a_j<b_j\) 一定是最优方案。
证明:
-
\((a_ib_j+a_jb_i) - (a_ia_j+b_ib_j)=(b_i-a_i)(a_j-b_j)\)
-
因为 \(b_i-a_i>0,~a_j-b_j<0\)
-
因此 \(a_ib_j+a_jb_i<a_ia_j+b_ib_j\)
所以,我们令 \(a_i<b_i\),那么 \(A\times B\) 就有最小值。
B - New Place
题意:
你有两个长为 \(n \le 200000\) 的字符串 \(S, T\).
你可以进行以下操作:
- 将 \(S\) 的第一个字符放到 \(S\) 任意一个位置上。
问最少多少次操作,能让 \(S=T\) ?若不可能,输出 \(-1\)。
思路:
显然,\(S\) 不进行操作的是一个后缀(可能为 \(0\))。
所以,我们要在 \(T\) 中找到一个最长子序列,满足它是 \(S\) 的一段后缀。
答案就是 \(n\) 减去最长子序列的长度。
C - Roller
题意:
给出两个长为 \(n\le 5000\) 的序列 \(A, B\),每次你可以将 \(a_i\) 替换为 \(a_{i+1}\)(如果要替换 \(a_n\),则 \(a_{n+1}=a_1\))。
问是否能够在若干次操作后,令 \(A = B\) ?
思路:
当 \(A\) 中存在 \(a_i=a_{(i\bmod n)+1}\),那么 \(A\) 是可以进行循环位移的。
因此,我们将问题分为两种情况:
- 不存在 \(b_i=b_{(i\bmod n)+1}\) (注意这里是 \(b\))
那么,给出的 \(A,B\) 必须满足 \(A=B\),答案才为 Yes。
- 存在 \(b_i=b_{(i\bmod n)+1}\)
对于 \(B\) 上一个连续段 \([i,j]\)(即 \(b_i = b_{i+1}=...=b_j\)),我们只需要满足 \(b_j=a_j\),那么前面的部分都可以通过操作得到。
因此我们可以将 \(B\) 的连续段都缩减成一个数,判断它是否为 \(A\) 上一个子序列。
当然,\(A\) 可以进行循环位移,每次循环后,都要进行一次判断。
时间复杂度为 \(O(n^2)\)
D - A + B > C
题意:
你要猜测一个长为 \(n\le 2000\) 的排列 \(P\)。
每次你可以询问 \(i,j,k\) (可以相同),得到 \(P_i+P_j>P_k\) 是否为真。
你最多可以询问 \(25000\) 次,并确定 \(P\)。
思路:
首先给出一个整体的思路:
通过 \(O(n)\) 的方法找到 \(P_i=1\) 的位置,然后通过 \(O(n\log n)\) 确定每个数。
- 找出 \(P_i=1\):
其实这无非是找出最小值。
对于 \(P_i,P_j\),如果有 \(P_i+P_i>P_j\) 且 \(P_j+P_j>P_i\),那么 \(P_i\) 和 \(P_j\) 一定都不是 \(1\)。
如果有 \(P_i+P_i>P_j\) 且 \(P_j+P_j<=P_i\),那么明显有 \(P_i>P_j\);反之亦然。
因此,我们可以假设当前最小值为 \(x\),并从 \(i\in [1, n]\) 扫过去:如果出现情况 \(1\),那么就令 \(x=i+1\);如果出现情况 \(2\),就让 \(x=i\);否则不变。
一共需要的次数是 \(2n\)。
- 确定每个数:
我们可以用归并排序,得到 \(P\) 有序情况下的坐标序列。
对于 \(P_i,P_j\),如果有 \(P_i+1>P_j\),那么就说明 \(P_i>P_j\);否则 \(P_i<P_j\)。
通过这个,就代替了排序中的大小比较的操作。
次数是 \(n\log n\) 的。
\(2n+n\log n\approx 24000\),实际上跑不满。