题意:给定一个长度为 $2n$ 的合法括号序列,每个左括号有一个权值,每次你可以把 $p(A)(B)q$ 改成 $p(A()B)q$ 的形式,代价为 $(A)$ 的第一个左括号乘 $x$ 加上 $(B)$ 的第一个左括号乘 $y$($A, B$ 必须是合法括号序列,$p, q$ 无限制),或者任意交换相邻的合法括号序列,不需要代价。问最少需要多少代价才能使得括号序列不包含 $()()$ 的结构。$n\leq 4\times 10 ^ 5$,$0\leq x, y\leq 1$,$a_i\leq 10 ^ 7$。
考虑我们用括号树来刻画这个变换。首先将括号转成树的方法是一对括号代表一个节点,然后内部的都是在他子树内部的。那么我们可以用图表示这个变化过程:
由图可以看出我们相当于用 A 把 B push 到了下一层,实际上其他的都没有变化。由于我们最后需要把整棵树变成一条链,所以其实中间的父子关系其实是没有关系的,我们只关心每个点所在的层数。
x = 0,y = 0
答案显然为 0。
x = 0,y = 1
这个相当于我们需要计算 B 的贡献,那么显然我们需要把最大的留在本层,这样代价尽量小。用一个 std::multiset
暴力维护即可做到 $O(n\log n)$。
x = 1,y = 1
我们计算的单层答案就是 $mn\times (sz - 2) + sum$,容易发现还是把最大的保留在当前层即可。复杂度仍然是 $O(n\log n)$。
x = 1,y = 0
现在我们计算的单层答案就是 $mn\times (sz - 2) + w$,$w$ 表示最后留下的权值。注意到除了最后一层的权值以外,其他的权值都被 $w$ 算了一遍。那么我们可以枚举最后一层的权值,这样的话剩下的就和前面的差不多,把最大的保留在当层即可,复杂度 $O(n ^ 2\log n)$。
注意到如果当前层个数 $\geq 3$ 的话,我们容易发现最大值和最小值都是有意义的,因为最小值可以让后面层贡献减少,而保留最大值到最后一层也是好的。难点在于我们对于个数 $=2$ 的情况 push 谁。
注意到一个性质就是 $sz$ 一定形如一个单峰的形式,而且下降一定是每次减 1。也就是说 $sz = 2$ 一定出现在前缀一段和倒数第二层。倒数第二层显然下放最大值,那么前面的应该怎么下放呢?
注意到我们前面说到只有最小值和最大值是有意义的,这一段 $sz = 2$ 最后只会下放一个值,那么这个值一定是最大值或者最小值。两个分别做就好了。复杂度 $O(n\log n)$。
1 | LL solve(int st, int v) |