更新并检查包含括号的子串是否正确

Update and check if the substring containing brackets is correct

问题是:

时限:0.2s

在这些情况下,定义了正确的括号表达式:

我的主要思路和CodeForces上的问题380C类似,http://codeforces.com/blog/entry/10363

然后我检查给定范围内的最长子序列是否等于范围的长度,所以我会得到答案。但是我有时间限制错误。

我整天都在网上搜索这个,但我没有得到答案。如果你能帮助我,我将不胜感激。 :)

这是我的代码:https://github.com/hoangvanthien/GH_CppFiles/blob/master/SPOJ/NKBRACKE.cpp

有效括号序列的条件是:

  • 子串长度为偶数

  • 左括号和右括号的个数相等

  • 在序列中的任何一点,都没有闭括号数大于开括号数的点。

所以,我们可以将原来的开括号和闭括号字符串转换成数字序列,每个数字代表从序列开始开始的开括号和闭括号之间的差值。每个左括号,我们将加一,并为关闭减一。

例如,对于 ((())))) -> 我们有序列 { 1, 2 , 3, 2 , 1, 0, -1, -2 }

所以,要测试一个子串是否有效,例如子串(2, 5),也就是())),我们需要看看在任何一点,打开和关闭之间的差异是否为负.从上面的序列中,我们有 {3, 2, 1, 0},我们需要为每个元素减去 2,因为我们需要从字符串的开头删除那些不在子字符串中的括号。 -> 我们有 {1, 0, -1, -2} -> 所以子字符串无效。

理解了以上思路后,我们就可以有自己的解决方案了。

  • 我们需要的是一个数据结构,可以快速更新一个范围。例如,如果我们在索引 3 处从 ( 更改为 ),那么我们需要从索引 3 开始的所有元素减去 -2

  • 而我们需要数据结构快速return一个范围的最小值(我们只需要关心最小值)。

根据所有这些要求,我们可以使用 Segment tree,它为您提供 O(log n) 更新和 O(log n) 检索。

伪代码

SegmentTree tree;

Initialize the tree with original sequence

for each query in the tree
   if( query type is update)
      if(change from ) to ()
         increase all value by 2 from range index to n
      else if(change from ( to ) )
         decrease all value by 2 from range index to n
   else
      int min = tree.getMinimumValueInRange(u, v)
      int notInSubstring = tree.getMinimumValueInRange(u - 1, u - 1)
      if(min - notInSubstring < 0)
          print Invalid 
      else if( length of substring is not even)
          print Invalid
      else if( tree.getMinimumValueInRange(v, v) != notInSubstring)//Number of open and close brackets are not equaled.
          print Invalid