【線分ツリー】Codeforces Round#223(Div.1)C-Sereja and Brackets
2825 ワード
オフラインで、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
", ans[i]);
}
int main()
{
read();
work();
return 0;
}