【Gym 100803 G】Flipping Parentheses

题意:给一个合法括号序列,然后现在每次把一个位置上的括号反转,问反转另一个位置使得括号序列重新变得合法的最小位置是哪里。

思路:首先我们要分两种情况考虑。

  • 我们反转的是(

那么聪明的读者一定会发现我们只需要把第一个)给反转就好了。

原因就是因为我们原来想要给打开括号数量\(+1\),而现在变成了\(-1\),所以后面的肯定会有一个\(-1\)的打开括号数量,于是我们必须把前面的一个补上去,越早越好。

  • 我们反转的是)

这就比较麻烦了。首先我们果断二分。

那么考虑一下我们如果要反转第\(i\)位,需要满足什么条件。

首先我们这次的括号序列不合法是因为多了\(2\)个打开的左括号。

那么我们现在从(改一个为)的目的是要让这个\(2\)消下去。

并且还要满足每时每刻的打开括号数量都\(\ge 0\)。

所以我们就需要一个线段树来维护每一位上的打开的括号数量,然后保证从\(i\)到\(n\)的每一位上的打开括号数量都\(\ge 2\)即可。因为我们现在是把(改成),减少了两个打开的括号数量。

我在写的时候只是维护了每一位上是((\(1\))还是)(\(-1\)),于是十分不爽地发现要维护最小前缀和,很悲伤地在线段树中维护了个结构体,就显得代码比较丑。

需要注意的是如果这样写我们只能判断\(\text{sum}(1,i-1)+\min(i,n)\ge 2\)了。复杂度\(\times 2\)。跑得贼慢。

需要注意我们这样二分出的\(i\)是否真的是个(。(如果我们费尽心机竟然把一个)该回去了就不太好了)

假如我们第一个成功的地方是一个),那么我们上一个位置的时候肯定可以满足(因为当前这位会使所有的和更小

那么矛盾,证毕。

只是注意下二分的时候找的是最前的那个就好了。

上一篇:[leetcode] 861. Score After Flipping Matrix


下一篇:Obect,对象,map,Json互相转换