CodeForces-380C:Sereja and Brackets(线段树与括号序列)
Sereja has a bracket sequence s1, s2, ..., sn, or, in other words, a string s of length n, consisting of characters "(" and ")".
Sereja needs to answer m queries, each of them is described by two integers li, ri(1 ≤ li ≤ ri ≤ n). The answer to the i-th query is the length of the maximum correct bracket subsequence of sequence sli, sli + 1, ..., sri. Help Sereja answer all queries.
You can find the definitions for a subsequence and a correct bracket sequence in the notes.
Input
The first line contains a sequence of characters s1, s2, ..., sn (1 ≤ n ≤ 106) without any spaces. Each character is either a "(" or a ")". The second line contains integer m (1 ≤ m ≤ 105) — the number of queries. Each of the next m lines contains a pair of integers. The i-th line contains integers li, ri (1 ≤ li ≤ ri ≤ n) — the description of the i-th query.
Output
Print the answer to each question on a single line. Print the answers in the order they go in the input.
Example
())(())(())(
7
1 1
2 3
1 2
1 12
8 12
5 11
2 10
0
0
2
10
4
6
6
题意:给定由‘(’和‘)’组成的字符串序列,然后Q个询问,每次回答区间最多有多少个匹配的括号。
思路:分治的思想,当前的括号匹配对于左区间的匹配数+右区间的匹配数+min(左区间的未匹配的左括号,右区间的未匹配的右括号),同时改变当前区间未匹配的括号数。
注意:因为有3个参数需要传递,所以用结构体(因为要修改未匹配括号数)。
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=1000010; char c[maxn]; struct in { int a,b,sum; in(){ a=0; b=0; sum=0;} }s[maxn<<2]; void read(int &res) { char c=getchar();res=0; for(;c>'9'||c<'0';c=getchar()); for(;c<='9'&&c>='0';c=getchar()) res=(res<<3)+(res<<1)+c-'0'; } struct segment_tree { void pushup(int Now) { int tmp=min(s[Now<<1].a,s[Now<<1|1].b); s[Now].sum=s[Now<<1].sum+s[Now<<1|1].sum+tmp; s[Now].a=s[Now<<1].a+s[Now<<1|1].a-tmp; s[Now].b=s[Now<<1].b+s[Now<<1|1].b-tmp; } void build(int Now,int L,int R) { if(L==R) { s[Now].a=(c[L]=='('?1:0); s[Now].b=(c[L]==')'?1:0); s[Now].sum=0; return ; } int Mid=(L+R)>>1; build(Now<<1,L,Mid); build(Now<<1|1,Mid+1,R); pushup(Now); } in query(int Now,int L,int R,int l,int r) { if(l<=L&&r>=R) return s[Now]; int Mid=(L+R)>>1; in w,e,res; if(l<=Mid) w=query(Now<<1,L,Mid,l,r); if(r>Mid) e=query(Now<<1|1,Mid+1,R,l,r); res.sum=min(w.a,e.b); res.a=w.a+e.a-res.sum; res.b=w.b+e.b-res.sum; res.sum+=w.sum+e.sum; return res; } }Tree; int main() { int N,Q,x,y; scanf("%s",c+1); N=strlen(c+1); Tree.build(1,1,N); read(Q); while(Q--){ read(x); read(y); printf("%d\n",2*Tree.query(1,1,N,x,y).sum); } return 0; }