传送门。
这道题是经典的线段树优化 DP。
设 \(f_{i,j}\) 为前 \(i\) 个数,分成 \(j\) 段的最大收益。
有 \(f_{i, j} = \max f_{i', j-1} + val(i'+1, i)\),其中 \(val(l, r)\) 表示子段 \(l\) 到 \(r\) 的不同数个数。
进一步地,我们记 \(g_{i'}\) 为 \(i'+1\) 到当前 \(i\) 的子段的不同数个数。每一轮 \(i-1 \to i\),有哪些 \(g\) 的值变了呢?
记 \(last_i\) 为 \(a_i\) 上一次出现的位置。新加进来一个 \(a_i\),并不会影响 \(last_i\) 之前的 \(g\) 值,只会让 \(g_{last_i} \sim g_{i-1}\) 区间 \(+1\)。
更进一步地,如果外层循环枚举 \(j\),内层循环枚举 \(i\),就有 \(f_{i, j} = \max f_{i', j-1} + g_{i'}\)。我们用一个数据结构维护 \(f_{i, j-1} + g_i\)。\(g\) 的修改会带来线段树的区间加,求 \(f_{i, j}\) 需要区间最大值。可以使用线段树维护。故做完。
时间复杂度 \(O(nk\log n)\)。
submission.