Sereja and Brackets CodeForces - 380C (树状数组+离线)
Sereja and Brackets
題目鏈接: 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 10Output
00210466Note
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 ?()(())(())?.
題意:
給你一個只含有'(' 和')' 的字符串,
以及q個詢問,每一個詢問給你兩個整數l和r,代表一個區間。對于每一個詢問,讓你輸出區間中能選出最長的子序列是合法的括號序列的長度。
思路:
對詢問區間進行離線保存,以右端點升序來排序,
然后從坐向右掃描,用stack來維護每一個還沒被匹配到的(字符的下標,
當來一個)字符的時候,將其和棧頂的那個(匹配,同時用樹狀數組在(的下標的數值上+2
然后走到每一個區間的右端點時對區間的答案進行更新。
為什么這樣寫可以呢?
因為我們可以通過分析發現,字符串中每一個)字符在區間中可以固定匹配到一個(使其區間答案最右。
細節見代碼:
#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';}} }轉載于:https://www.cnblogs.com/qieqiemin/p/11491979.html
總結
以上是生活随笔為你收集整理的Sereja and Brackets CodeForces - 380C (树状数组+离线)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SMTP 服务器要求安全连接或客户端未通
- 下一篇: asp 下载函数