Codeforces Round 943 (Div. 3)(C-G)
C
题意:对于 \(i \in [2, n]\),给定 \(x_i = a_i \bmod a_{i - 1}\),构造一种符合条件的 \(a\),\(1 \le a_i \le 10^9\)。
分析 \(a_{i}\) 和 \(a_{i -1}\) 的大小关系。
-
\(x_i < a_i \longrightarrow a_{i - 1} < a_i\)。
-
\(x_i = a_i \longrightarrow a_{i - 1} > a_i\)。
为了不越界,\(a_i\) 和 \(a_{i - 1}\) 都要尽可能大。
于是可以从 \(n\) 往前构造。
- \(a_n = 10^9\)。
- \(x_i < a_i\),\(a_{i - 1} = a_i - x_i\)。
- \(x_i = a_i\),\(a_{i - 1} = 10^9\) 。
D
最后一定是停在某个点不动,枚举最后停留的点即可。
E
令 \((i, j)\) 表示第 \(i\) 行第 \(j\) 列。
-
若 \(j = 1\) 或 \(j = 2\),填 \((1, j)\)。
-
否则填 \((j, j)\)。
这样 \(2n - 2\) 种长度都有了,从结论反推正确性很简单。
F
题意:给定序列 \(a\),每次询问一对 \([l, r]\) 是否能划分成大于 \(1\) 段使得各段异或值相等。
区间问题先转化为前缀异或。
-
\(s_r \oplus s_{l - 1} = 0\)。
题目保证了 \(l < r\),所以一定有解。
-
\(s_r \oplus s_{l - 1} = v\)。
-
一定划分为奇数段。
-
如果能划分成奇数段,则一定能划分成 \(3\) 段。
-
最终划分的异或值一定是 \(v\)。
于是问题转变为是否能把 \([l, r]\) 分成三段,使得每段异或值都为 \(v\)。
找到最大的 \(i < r\) 使得 \(s_r \oplus s_i = v\),如果找不到则无解。
找到最大的 \(j < i\) 使得 \(s_i \oplus s_j = v\),如果找不到或 \(j < l - 1\) 则无解。
具体实现可以维护一个
map<int, vector<int>>
。 -
G1
题意:将字符串 \(s\) 划分成 \(k\) 段,问每段的最长公共前缀(\(\text{LCP}\))。
如果存在划分使得 \(\text{LCP}\) 为 \(v\) ,则任意 \(v' < v\) 都存在划分。
单调性存在,二分前缀长度。
令前缀字符串为 \(t\),\(s\) 种最多有 \(x\) 个不相交的子串 \(t\)。
如果 \(x \ge k\),则存在划分使得 \(\text{LCP}\) 为 \(t\)。
可以用 \(\text{kmp}\) 或字符串哈希求出 \(x\)。
G2
题意:将字符串 \(s\) 划分成 \(k\) 段,问每段的 \(\text{LCP}\),求出 \(L \le k \le R\) 的每个答案。
\(k\) 越大,答案 \(l\) 越小,最终的答案序列单调不增。
根号分治。
当 \(k \le \sqrt n\) 时,用 \(G1\) 的方法暴力计算。
当 \(k \ge \sqrt n\) 时,\(l \le \sqrt n\)。
对于每个前缀 \(l \le \sqrt n\) 分别计算出答案 \(x\)。
\(x\) 能划分出 \(l\),则 \(\forall x' < x\) 也能划分出 \(l\),最后对答案取个后缀 \(\max\) 即可。
实测 \(O(n\sqrt n \log n)\) 的复杂度还是很吃紧,可以加记忆化剪枝。