离线,按照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; }