CF1209G Into Blocks

题意:给出一个长度为 的序列。

我们需要达成:如果存在 ,那么必须满足所有 都必须在序列中连续。

可以进行的操作:将所有的 的变为任意你指定的 ,并且花费 元素的个数的代价。

求达成目标的最小化费。有 次单点修改。

,时限 。


先来求达成目标的最小化费。

对于某种颜色 ,设其最左侧为 ,最右侧为 。

若最终要保留这种颜色,肯定要把 都染成 。

这样不难发现,若 有交集,那么 两种颜色肯定只能保留一个。

我们把有交集的区间并起来,每个并中保留众数即可。


接下来考虑动态维护。

修改一个位置,可能会导致两个区间变化。

对于每个区间 ,给 加一,则 为每个线段并区间的分界线(右侧)。

现在需要维护每两个 之间的区间众数出现次数和。

维护区间最左端的 和最右端的 ,合并时考虑跨越分界线的两个 。

实际实现中需要维护最左端和最右端的最小值,以及各个最小值之间的众数和。

每次合并区间时,需要查询一次区间众数。

一般的区间众数解法较为复杂,但是本题中保证所有可能作为答案的数都在询问区间内。

那么我们给 的任意一次出现赋值 ,众数就是区间最大值,这可以用另一棵线段树维护。

这能够做到 。

考虑在线段树上额外维护左端最小值到左边界的 ,右端最小值到右边界的 即可做到 。