离线,按照r递增的顺序将询问排序,然后用线段树做。。

#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 1000005
#define maxm 1000005
#define eps 1e-7
#define mod 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid 
#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
//head

struct node
{
	int l, r, id;
}p[maxn];

stack<int> ss;
char s[maxn];
int maxv[maxn << 2];
int add[maxn << 2];
int ans[maxn];
int m;

void build(int o, int L, int R)
{
	maxv[o] = add[o] = 0;
	if(L == R) return;
	int mid = (L + R) >> 1;
	build(lson);
	build(rson);
}

void pushdown(int o)
{
	if(add[o]) {
		maxv[ls] += add[o];
		maxv[rs] += add[o];
		add[ls] += add[o];
		add[rs] += add[o];
		add[o] = 0;
	}
}

void pushup(int o)
{
	maxv[o] = max(maxv[ls], maxv[rs]);
}

void update(int o, int L, int R, int ql, int qr)
{
	if(ql <= L && qr >= R) {
		maxv[o] += 2;
		add[o] += 2;
		return;
	}
	pushdown(o);
	int mid = (L + R) >> 1;
	if(ql <= mid) update(lson, ql, qr);
	if(qr > mid) update(rson, ql, qr);
	pushup(o);
}

int query(int o, int L, int R, int ql, int qr)
{
	if(ql <= L && qr >= R) return maxv[o];
	int mid = (L + R) >> 1, ans = 0;
	pushdown(o);
	if(ql <= mid) ans = max(ans, query(lson, ql, qr));
	if(qr > mid) ans = max(ans, query(rson, ql, qr));
	pushup(o);
	return ans;
}

int cmp(node a, node b)
{
	return a.r < b.r;
}

void read()
{
	scanf("%s", s+1);
	scanf("%d", &m);
	for(int i = 1; i <= m; i++) scanf("%d%d", &p[i].l, &p[i].r), p[i].id = i;
}

void work()
{
	int n = strlen(s + 1);
	build(1, 1, n+1);
	sort(p+1, p+m+1, cmp);
	for(int i = 1, j = 1; i <= n && j <= m; i++) {
		if(s[i] == '(') ss.push(i);
		else if(!ss.empty()) update(1, 1, n+1, 1, ss.top()), ss.pop();
		while(j <= m && p[j].r == i) {
			ans[p[j].id] = query(1, 1, n+1, p[j].l, n+1);
			j++;
		}
	}
	for(int i = 1; i <= m; i++) printf("%d\n", ans[i]);
}

int main()
{
	read();
	work();

	return 0;
}