把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

QOJ #8820. Exchanging Kubic 2

首先我们来考虑给定一个序列,如何计算最小的权值。

不妨将其差分来看,每次操作相当于向左向右找到第一个位置满足差分值 \(>0\),然后将这两个位置分别 \(-1\)

记三元组 \((l_i,x_i,r_i)\) 表示在 \(x\) 操作一次,左边在第 \(l_i\) 个差分值位置处减了 \(1\),右边在第 \(r_i\) 个差分值位置处减了 \(1\)

如果对于两对三元组 \((l_1,x_1,r_1),(l_2,x_2,r_2)\),满足 \(x_1<l_2<r_1<x_2\),这是不可能的,因为假设第一个三元组先操作,那么 \(l_2\) 处肯定已经没有值了所以才会跳过。而如果第二个三元组先操作,则 \(r_1\) 处也没有值了。同理不能有 \(l_1<l_2<x_1<x_2\),因此,任意两个三元组对应的区间 \([l_i,r_i]\) 只能是相离或者包含。

如果一个三元组的区间包含了另一个三元组的区间,那么被小的三元组就要早于大的三元组操作,这显然是一个 DAG。因此只要我们确定了一些三元组满足不交或者包含,那么就是合法的。

然后就可以看出,三元组的两边是独立的,也即 \(l_i\)\(r_i\) 没有关系,只需要分别满足 \(\leq x\)\(\geq x\) 即可。

这变成一个匹配问题,容易得到一个贪心:从左到右对于每个差分值,先找 \(\leq x\) 能填的填进去,然后找 \(\geq x\) 能填的填进去即可。

然后可以 DP 了,设 \(f_{i,j,k}\) 表示到了第 \(i\) 个数,选了 \(j\),差分值总和是 \(k\)。若 \(k<i\),则说明前面有值没有用到,补齐成 \(i\)。若 \(k>n+i-1\),说明空位太多了,则 \(k-(n+i-1)\) 就会被计入答案。这个 DP 容易前缀和优化到 \(O(n|S|(n+|S|))\)

submission

posted @ 2024-06-25 18:47  275307894a  阅读(20)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end