Sereja and Brackets CodeForces - 380C (Fenwick tree + offline)

Sereja and Brackets

Topic links: codeforces - 380C

Sereja has a bracket sequence s1, s2, ..., *s**n, 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, ..., *s**n* (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.

Examples

Input

())(())(())(71 12 31 21 128 125 112 10

Output

00210466

Note

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

A 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 «()(())(())».

Meaning of the questions:

You give a string containing only '(' and ''), and

And a query q, each of two integers to ask you to l and r, represents an interval. For each inquiry, so that you can select the output interval is the length of the longest sequence legitimate parentheses sequences.

Ideas:

Inquiry interval stored offline, sorted in ascending order to the right end,

Then take the right scanning, each with a stack to maintain not be matched to a (subscript characters,

Come on when a) the character of the time, and that it (match top of the stack, at the same time with the tree in the array (the target value +2

Then the answer is updated when the interval came right end point of each interval.

Why you can write it?

Because we can through the analysis found that for each string) character in the interval can be fixed to match a (so far right answer section.

See details Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
struct node {
    int l, r;
    int id;
} a[maxn];
char s[maxn];
int n;
int m;
bool cmp(node aa, node bb)
{
    return aa.r < bb.r;
}
int tree[maxn];
int lowbit(int x)
{
    return x & (-1 * x);
}
void add(int x, int val)
{
    while (x <= n) {
        tree[x] += val;
        x += lowbit(x);
    }
}
int ask(int x)
{
    int res = 0;
    while (x) {
        res += tree[x];
        x -= lowbit(x);
    }
    return res;
}
int ans[maxn];
int main()
{
    //freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    gbtb;
    cin >> s + 1;
    n=strlen(s+1);
    cin >> m;
    repd(i, 1, m ) {
        cin >> a[i].l >> a[i].r;
        a[i].id = i;
    }
    sort(a + 1, a + 1 + m, cmp);
    stack<int> st;
    while (sz(st)) {
        st.pop();
    }
    int pos = 1;
    repd(i, 1, m) {
//        chu(pos);
        repd(j, pos, a[i].r) {
            if (s[j] == '(') {
                st.push(j);
            } else {
                if (sz(st)) {
                    add(st.top(), 2);
                    st.pop();
                }
            }
        }
        ans[a[i].id] = ask(a[i].r) - ask(a[i].l - 1);
        pos = a[i].r + 1;
    }
    repd(i,1,m)
    {
        printf("%d\n",ans[i] );
    }

    return 0;
}

inline void getInt(int *p)
{
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    } else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}



Guess you like

Origin www.cnblogs.com/qieqiemin/p/11491979.html