The problem is:
Given the string with length of n, and m queries.
Each query is one of two cases:
Time limit: 0.2s
In these cases, a correct brackets expression is defined:
a string with length of 0
a string only contains '(' and ')'
if A is a correct brackets expression, then (A) is also a correct brackets expression
if A and B is correct brackets expressions, then AB is also a correct brackets expression
My main idea is similar to the problem 380C on CodeForces, http://codeforces.com/blog/entry/10363
Then I check if the longest subsequence in the given ranges is equal to the length of ranges, so I will get the answer. But I got time limit error.
I have been searching for this on the internet all day but I haven't got the answer. I will be grateful if you help me. :)
Here is my code: https://github.com/hoangvanthien/GH_CppFiles/blob/master/SPOJ/NKBRACKE.cpp
The conditions for a valid bracket sequence are:
Length of the substring is even.
The number of open and close brackets are equaled.
At any point in the sequence, there is no point which number of close brackets is greater than the number of open brackets.
So, from the original string of open and close brackets, we can convert it into sequence of number, each number represent the difference between open and close brackets from the beginning of the sequence. Each open brackets, we will plus one, and minus one for close.
For example, for ((()))))
-> we have the sequence { 1, 2 , 3, 2 , 1, 0, -1, -2 }
So, to test if a substring is valid, for example, substring (2, 5), which is ()))
, we need to see if at any point, the difference between open and close is negative. From above sequence, we have {3, 2, 1, 0}, and we need to minus 2 for each element, as we need to remove those brackets from the beginning of the string, which are not in the substring. -> we have {1, 0, -1, -2} -> so the substring is invalid.
After understand above idea, we can have our solution for the problem.
What we need is a data structure, which can quickly update a range. For example, if we change from (
to )
at index 3, so we need to minus -2
to all element from index 3 onward.
And we need the data structure to quickly return the minimum value of a range (we only need to care about minimum value).
And from all of that requirements, we can use a Segment tree, which give you O(log n) update and O(log n) retrieve.
Pseudo code
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