ARC196 Solution A-D
E 可能待会补。
D 因为哈希写挂调了好久,没时间做 E 了!!
A - Operations on a Stack
一次加入可以和删除抵消,等价于这两次都不操作。
于是变成两个相邻选的位置中间夹的没有选择的位置长度必须为偶数。
直接 dp 即可。
B - Minimum Cost Sort
贪心,发现只往后移动一定是比往前移动优的。
每次找一个最大值往后移动到目标位置。直接 BIT 维护。
C - Cost to Flip
考虑 \(x\to y\) 表示将某一位从 \(x\) 变为 \(y\)。则如果是 \(0\to 0\) 则直接跳过。
对于 \(1\to0\) 和 \(0\to1\),则发现我们优先进行前者更优,这样可以使得 \(1\) 的存在时间更短。
对于 \(1\to0\) 内部的顺序,发现优先选择 \(C_i\) 大的进行操作一定更优。\(0\to 1\) 相反。实现上可以通过维护两个树状数组统计贡献。
对于 \(1\to1\),我们发现有两种可能,分别是中间不进行操作和 \(1\to0\to1\)。发现优先通过 \(0\) 中转的一定是 \(C_i\) 较大的点。
考虑把通过 \(0\) 中转的拆成上文的两种操作,然后分别插入即可。按 \(C_i\) 排序插入,动态维护过程中的答案。需要记录 \(1\to0\) 和 \(0\to1\) 的贡献 \(sum\),不修改的 \(1\to1\) 的 \(C_i\) 的总和 \(cnt\) 和总共用时 \(t\),则用 \(sum+t\cdot cnt\) 更新答案。
时间复杂度 \(O(n\log V)\)。
D - Reverse Brackets
考虑建树表示括号之间嵌套的关系,套路地,我们 dfs 下去,每次只解决某个区间内的子问题。
对于某个点的叶子,反转等价于随意交换它的子结点。考虑通过组合数计算贡献。
由于最后统计的是不同串的数量,因此当两个子结点的子树的结构相同时可能会算重。考虑通过树上哈希找出相同的子树,假设某个结构出现次数为 \(c\),其内部的答案为 \(ans\),则贡献是 \(ans^c\)。对于结构不同的点,直接乘上多重组合数计算穿插方式即可。
时间复杂度 \(O(n^2)\)。实现时通过 map 去重和判断。