ARC150F Constant Sum Subsequence 解题记录
题意:
给定长度为 \(n\) 的序列 \(A\),保证对每个 \(i\in[1,S]\),\(i\) 都在 \(A\) 中出现了至少一次。
令 \(X\) 表示 \(A\) 重复 \(S\) 次组成的序列。
求最小的 \(L\),满足:
对每个和为 \(S\) 的序列 \(B\),\(B\) 都是 (\(X\) 的前 \(L\) 个元素组成的序列) 的子序列。
\(n \le 1.5\times 10^6, S\le2\times 10^5\)
考虑一个朴素的 dp。
令 \(dp_i\) 表示:\(X\) 的前 \(i\) 个元素组成的序列,可以包含所有的和不大于 \(dp_i\) 的序列。
易知有这样的转移:
维护一个辅助数组 \(g\),其中 \(g_i\) 表示结尾为 \(i\) 的序列此时的答案。
枚举每个 \(i \in [1,n\times S]\),令:
\[dp_i=\min_{j=1}^S g_j\\
g_{X_i}=\max(g_{X_i},dp_{i-1}+X_i)
\]
采用适当的维护方法,就可做到复杂度 \(O(n\times S)\)。
仔细分析可知 \(dp_i\) 只有 \(O(S\log S)\) 个不同的取值。
这引导我们得到和 \(dp_i\) 取值强相关的做法。
我们考虑对 \(dp_i\) 相同的一段进行快速转移。
维护 \(L\),表示此时只考虑 \(i<L\) 的 \(dp_i\) 转移。
接下来从小到大对最小的一些 \(g_i\) 一次性更新这些:
\[g_i=dp_{*}+i
\]
如果此时 \(g_i\) 没有发生变化,就更新 \(L\),并令 \(g_i\to g_i+i\)。
仔细分析,可知每当 \(g_i\) 更新两次,\(g_i\) 至少变大 \(i\)。
总复杂度 \(O(S\log^2(n+S))\),可以通过此题。