Question:
A string of parentheses
Ask how many square brackets can be matched in a range [L, R ].
Analysis:
We can process two arrays.
Sum [I] 1... the number of square brackets that can be matched in I
Left [I] 1... the number of left parentheses that cannot match
These two Arrays can be easily scanned and dynamically maintained.
We can first obtain the prefix and, that is
1. How many matching right parenthesis sum in. M [m]
Then, we can obtain the right brackets that can be matched legally in sum [R]-sum L-1] and range [L, R ].
However, the matching of the right brackets includes matching with the left brackets in [1 L-1 ].
So we subtract left [L-1],
This will remove the left brackets matching [1 L-1] and [R + 1 ...].
So you have to add this part.
What is this part? This is the key and hard to understand.
This part is Min (left [l]... left [R]). Why?
...... (.. (............)...... (..............)........)
1 2 L 3 4 R 5 6
The red part is the query interval L, R
We can see that
We subtract parentheses.
However, parentheses 1 should not be subtracted. It is paired with parentheses 6.
Brackets 2 should be subtracted. It is paired with brackets 3.
If we take the minimum value of left on L and R, we can see that the minimum value falls between angle brackets 3 and angle brackets 4, which can avoid calculating angle brackets 4 (which matches angle brackets 5)
In addition, you can add brackets 1 that have been removed.
However, there is also a tricks. If there is no min position in the first position in the range of L and R in parentheses like 4.
It is really troublesome to judge this situation.
We will handle the following:
If left [L-1]-min (left [l]... left [R]) <0 is not subtracted; otherwise, minus (because l, the right brackets that can be matched in R cannot exceed sum [R]-sum L-1, the right parenthesis in the latter can also match the left parenthesis on 1 and L)
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>#include <vector>#include <queue>#define L(x) x<<1#define R(x) x<<1|1using namespace std;const int NN=1111111;char str[NN];char tmp[NN];int l[NN],r[NN];struct TREE{int x;}tr[NN*6];void build(int idx,int L,int R){if(L==R){tr[idx].x=l[L];return;}int mid=(L+R)/2;build(L(idx),L,mid);build(R(idx),mid+1,R);tr[idx].x=min(tr[L(idx)].x,tr[R(idx)].x);}int que(int idx,int ll,int rr,int L,int R){int mid=(L+R)/2;if(ll==L && rr==R){ return tr[idx].x;}if(rr<=mid){return que(L(idx),ll,rr,L,mid);}else if(ll>=mid+1){return que(R(idx),ll,rr,mid+1,R);}else{return min(que(L(idx),ll,mid,L,mid),que(R(idx),mid+1,rr,mid+1,R));}}int main(){#ifndef ONLINE_JUDGEfreopen("G:/in.txt","r",stdin);//freopen("G:/myout.txt","w",stdout);#endifcin>>(str+1);//cin>>tmp;int n;cin>>n;int len=strlen(str+1);for(int i=1;i<=len;i++){l[i]=l[i-1];r[i]=r[i-1];if(str[i]=='('){l[i]++;}else{if(l[i]){l[i]--;r[i]++;}}}build(1,1,len);while(n--){int x,y;cin>>x>>y;if(x==y){ cout<<0<<endl; continue;}int ans=r[y]-r[x-1];ans-=max(0,l[x-1]-que(1,x,y,1,len));cout<<ans*2<<endl;}}
Cf1_c sereja and brackets [idea + line segment tree]