CF1685C
题面
给定长度为 \(2n\) 的括号序列,你需要求出使用最少操作使括号序列变成合法的,并构造。
一次操作的定义为:
- 翻转(不是取反)这个括号序列的一个子串。
数据范围 :\(n\le 10^5\) 。
题解
确实是没有认真想,不过感觉想了也不一定会发现。
肯定先把 ()
转换为 \(1,-1\) ,记 \(s_i\) 为前缀合。
然后先考虑一次翻转 \([l,r]\) 子串会发生什么。
- \(j\in[1,l-1]\cup[r+1,2n],s_j\) 不变。
- \(j\in[l,r],s_j\leftarrow s_{l-1}+s_r-s_{l+r-j-1}\) 。
记 \(s_i\) 最大的 \(i\) 为 \(x\) 。(有相同的任取一个)
我们需要让最后 \(s_i\ge 0\) ,而注意到如果我们让 \(a_r\) 最大,\(s_{l-1}=0\) ,那么 \(s_r-s_{l+r-j-1}\ge 0\) ,这也就说明了我们可以用一次操作让 \([1,x]\) 全部满足。
既然前缀我们可以一次就处理掉,那么后缀有没有同样的性质呢?
同样,如果我们让 \(s_{l-1}\) 最大,\(s_r=0\) ,即 \(l=x,r=n\) ,也一定会有 \(s_{l+1}-s_{l+r-j-1}\ge 0\) ,所以我们可以用一次操作让 \([x+1,n]\) 全部满足。
所以答案的上界就是 \(2\) 了,所以我们就只用判断是否有 \(0/1\) 的解就可以了。
还是考虑上面列出来的翻转 \([l,r]\) 会带来的改变。
我们首先需要让 \(i\in[1,l-1]\cup[r+1,2n]\) 的 \(s_i\ge0\) ,也就是确定了 \(l,r\) 的选择范围。
然后再考虑第二个,我们肯定要让 \(s_r\) 最大,那么 \(r\) 就确定了,\(l\) 枚举一下判断是否合法就可以了。
复杂度是 \(O(n)\) 的。
ps:注意到 \(1/-1\) 是可以变成任意整数的,所以可能会有其他变体。
启发
- 对于有操作的问题,可以考虑用把操作带来的改变用公式列出来,这样比干想要好的多。