cf380 C. Sereja and Brackets
阿新 • • 發佈:2022-04-22
題意:
給定括號串。m次詢問,每次回答 \([x,y]\) 中的最長合法括號子列長度
思路:
線段樹,維護 \([l,r]\) 中失配的左括號數量 \(L\) 和右括號數量 \(R\)
合併相鄰區間:左半區間未匹配的左括號 可以和 右半區間未匹配的右括號 抵消一下
const signed N = 1e6 + 3; int n, m; char a[N]; #define mid ((l+r)>>1) #define lson u<<1 #define rson u<<1|1 #define ls lson,l,mid #define rs rson,mid+1,r int L[N<<2], R[N<<2]; void build(int u, int l, int r) { if(l == r) return void(a[l] == '(' ? L[u] = 1 : R[u] = 1); build(ls), build(rs); L[u] = L[lson] + L[rson] - min(L[lson], R[rson]); //pushup R[u] = R[lson] + R[rson] - min(L[lson], R[rson]); } PII ask(int u, int l, int r, int x, int y) { //[x,y]中失配括號數 if(r < x || l > y) return {0,0}; //沒交集 if(l >= x && r <= y) return {L[u], R[u]}; //包含關係 auto [tll, tlr] = ask(ls, x, y); auto [trl, trr] = ask(rs, x, y); //得合併一下 return {tll + trl - min(tll,trr), tlr + trr - min(tll,trr)}; } signed main() { iofast; cin >> a + 1 >> m; n = strlen(a + 1); build(1, 1, n); while(m--) { int x, y; cin >> x >> y; auto [tL, tR] = ask(1, 1, n, x, y); cout << y - x + 1 - tL - tR << endl; } }