zoukankan      html  css  js  c++  java
  • Sereja and Brackets(括号匹配)

    Description

    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.

    Input

    ())(())(())(
    7
    1 1
    2 3
    1 2
    1 12
    8 12
    5 11
    2 10

    Output

    0
    0
    2
    10
    4
    6
    6

    Note

    subsequence of length |x| of string s = s1s2... s|s| (where |s| is the length of string s) is string x = sk1sk2... sk|x| (1 ≤ k1 < k2 < ... < k|x| ≤ |s|).

    correct bracket sequence is a bracket sequence that can be transformed into a correct aryphmetic expression by inserting characters "1" and "+" between the characters of the string. For example, bracket sequences "()()", "(())" are correct (the resulting expressions "(1)+(1)", "((1+1)+1)"), and ")(" and "(" are not.

    For the third query required sequence will be «()».

    For the fourth query required sequence will be «()(())(())».

    解题思路:求连续子串中括号匹配的个数。括号匹配问题一般可以用栈来维护。对于每个右括号,其匹配的左括号是固定的,因此我们可以记录每个右括号匹配的左括号位置,对整个区间进行线扫描,同时用树状数组维护+离散化处理即可。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int maxn=1e6+5;
     5 const int maxv=1e5+5;
     6 char str[maxn];int n,m,pos,tree[maxn],ans[maxv];stack<int> st;
     7 struct node{int l,r,id;}query[maxn];
     8 bool cmp(node a,node b){return a.r<b.r;}///右端点排序
     9 inline int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 inline void print(int x){
    16     if(x<0)putchar('-'),x=-x;
    17     if(x>9)print(x/10);
    18     putchar(x%10+'0');
    19 }
    20 int lowbit(int x){return x&-x;}
    21 void add(int x,int val){
    22     for(int i=x;i<=n;i+=lowbit(i))tree[i]+=val;
    23 }
    24 int get_sum(int x){
    25     int ans=0;
    26     for(int i=x;i>0;i-=lowbit(i))ans+=tree[i];
    27     return ans;
    28 }
    29 int main(){
    30     while(~scanf("%s",str)){
    31         while(!st.empty())st.pop();n=strlen(str);
    32         memset(tree,0,sizeof(tree)),memset(ans,0,sizeof(ans));m=read();
    33         for(int i=0;i<m;++i)query[i].l=read(),query[i].r=read(),query[i].id=i;
    34         sort(query,query+m,cmp);pos=1;
    35         for(int i=0;i<m;++i){
    36             for(int j=pos;j<=query[i].r;++j){
    37                 if(str[j-1]=='(')st.push(j);///记录左括号的位置(物理位置)
    38                 else if(!st.empty())add(st.top(),2),st.pop();///单点更新
    39             }
    40             pos=query[i].r+1;///从下一个位置开始,避免重叠,O(n)遍历
    41             ans[query[i].id]=get_sum(query[i].r)-get_sum(query[i].l-1);
    42         }
    43         for(int i=0;i<m;++i)print(ans[i]),puts("");
    44     }
    45     return 0;
    46 }
  • 相关阅读:
    (元)黄公望---富春山居图(中国十大传世名画之八) 高清图下载
    Bloom Filter 原理与应用
    开始我的 JNI 入门吧
    javaScript的使用
    hash定义
    POJ3169 Layout(差分约束系统)
    青蛙的约会
    POJ 3414 Pots ( BFS , 打印路径 )
    你真的理解Java的this和super吗?
    十款优秀的在线JavaScript工具介绍
  • 原文地址:https://www.cnblogs.com/acgoto/p/10047496.html
Copyright © 2011-2022 走看看