[hdu5217]线段树

题意:给定一个只含'(',')'的括号序列,有m个操作,改变某个位置的括号或者询问区间[L,R]内的括号进行配对后剩下的第K个括号的位置(配对的括号从原序列中删掉)。

思路:首先对于一个括号序列,进行配对后剩下的括号序列必定是")))...)((...(("这种形式的,令(x,y)表示当前区间的剩下的右括号数为x,左括号数为y这个状态,不难发现它可以通过子区间来合并,因此考虑用线段树解决。对于单点更新比较容易,直接在叶子节点改变一下,然后向上更新即可,对于L,R,K这个询问,首先进行一次区间[L,R]的查找,得到最终的左括号和右括号数目,如果数目和小于K,则答案为-1,否则可以确定第K个括号的是哪种类型的括号,假设第K个括号是右括号,则问题转化为求第K个右括号的位置,在线段树上二分即可,二分的时候需要注意,假定答案在右区间,且左区间有x个右括号y个左括号,则在右区间应查找第K-x+y个右括号。

  1 #pragma comment(linker, "/STACK:102400000,102400000")
  2 
  3 #include <iostream>
  4 #include <cstdio>
  5 #include <algorithm>
  6 #include <cstdlib>
  7 #include <cstring>
  8 #include <map>
  9 #include <queue>
 10 #include <deque>
 11 #include <cmath>
 12 #include <ctime>
 13 #include <cctype>
 14 #include <set>
 15 #include <bitset>
 16 #include <functional>
 17 #include <numeric>
 18 #include <stdexcept>
 19 #include <utility>
 20 #include <vector>
 21 
 22 using namespace std;
 23 
 24 #define mem0(a) memset(a, 0, sizeof(a))
 25 #define mem_1(a) memset(a, -1, sizeof(a))
 26 #define lson l, m, rt << 1
 27 #define rson m + 1, r, rt << 1 | 1
 28 #define define_m int m = (l + r) >> 1
 29 #define rep_up0(a, b) for (int a = 0; a < (b); a++)
 30 #define rep_up1(a, b) for (int a = 1; a <= (b); a++)
 31 #define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
 32 #define rep_down1(a, b) for (int a = b; a > 0; a--)
 33 #define all(a) (a).begin(), (a).end()
 34 #define lowbit(x) ((x) & (-(x)))
 35 #define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
 36 #define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
 37 #define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
 38 #define pchr(a) putchar(a)
 39 #define pstr(a) printf("%s", a)
 40 #define sstr(a) scanf("%s", a)
 41 #define sint(a) scanf("%d", &a)
 42 #define sint2(a, b) scanf("%d%d", &a, &b)
 43 #define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
 44 #define pint(a) printf("%d
", a)
 45 #define test_print1(a) cout << "var1 = " << a << endl
 46 #define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
 47 #define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
 48 
 49 typedef long long LL;
 50 typedef pair<int, int> pii;
 51 typedef vector<int> vi;
 52 
 53 const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
 54 const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
 55 const int maxn = 2e5 + 7;
 56 const int md = 10007;
 57 const int inf = 1e9 + 7;
 58 const LL inf_L = 1e18 + 7;
 59 const double pi = acos(-1.0);
 60 const double eps = 1e-6;
 61 
 62 template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
 63 template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
 64 template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
 65 template<class T>T condition(bool f, T a, T b){return f?a:b;}
 66 template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
 67 int make_id(int x, int y, int n) { return x * n + y; }
 68 
 69 int ans;
 70 char s[maxn];
 71 
 72 struct SegTree {
 73     struct Node {
 74         int cl, cr;
 75     } tree[maxn << 2];
 76 
 77     Node merge(Node b, Node c) {
 78         Node a;
 79         a.cl = c.cl;
 80         a.cr = b.cr;
 81         if (b.cl <= c.cr) a.cr += c.cr - b.cl;
 82         else a.cl += b.cl - c.cr;
 83         return a;
 84     }
 85 
 86     void build(int l, int r, int rt) {
 87         if (l == r) {
 88             char ch = s[l - 1];
 89             tree[rt].cl = ch == '(';
 90             tree[rt].cr = ch == ')';
 91             return ;
 92         }
 93         define_m;
 94         build(lson);
 95         build(rson);
 96         tree[rt] = merge(tree[rt << 1], tree[rt << 1 | 1]);
 97     }
 98 
 99     void update(int u, int l, int r, int rt) {
100         if (l == r) {
101             swap(tree[rt].cl, tree[rt].cr);
102             return ;
103         }
104         define_m;
105         if (u <= m) update(u, lson);
106         else update(u, rson);
107         tree[rt] = merge(tree[rt << 1], tree[rt << 1 | 1]);
108     }
109 
110     Node query(int L, int R, int l, int r, int rt) {
111         if (L <= l && r <= R)  return tree[rt];
112         define_m;
113         if (R <= m) return query(L, R, lson);
114         if (L > m) return query(L, R, rson);
115         return merge(query(L, R, lson), query(L, R, rson));
116     }
117 
118     Node find1(int L, int R, int k, int l, int r, int rt) {
119         if (L <= l && r <= R && (k > tree[rt].cr || k <= 0 || ans)) return tree[rt];
120         if (l == r) {
121             ans = l;
122             return tree[rt];
123         }
124         define_m;
125         if (R <= m) return find1(L, R, k, lson);
126         if (L > m) return find1(L, R, k, rson);
127         Node buf = find1(L, R, k, lson);
128         if (ans) return buf;
129         return merge(buf, find1(L, R, k - buf.cr + buf.cl, rson));
130     }
131 
132      Node find2(int L, int R, int k, int l, int r, int rt) {
133         if (L <= l && r <= R && (k > tree[rt].cl || k <= 0 || ans)) return tree[rt];
134         if (l == r) {
135             ans = l;
136             return tree[rt];
137         }
138         define_m;
139         if (R <= m) return find2(L, R, k, lson);
140         if (L > m) return find2(L, R, k, rson);
141         Node buf = find2(L, R, k, rson);
142         if (ans) return buf;
143         return merge(find2(L, R, k - buf.cl + buf.cr, lson), buf);
144     }
145 };
146 SegTree ST;
147 int main() {
148     //freopen("in.txt", "r", stdin);
149     int T, n, m;
150     cin >> T;
151     while (T --) {
152         cin >> n >> m;
153         scanf("%s", s);
154         ST.build(1, n, 1);
155         rep_up0(i, m) {
156             int id;
157             sint(id);
158             if (id == 1) {
159                 int u;
160                 sint(u);
161                 ST.update(u, 1, n, 1);
162             }
163             else {
164                 int u, v, k;
165                 sint3(u, v, k);
166                 SegTree::Node buf = ST.query(u, v, 1, n, 1);
167                 if (buf.cl + buf.cr < k) {
168                     puts("-1");
169                     continue;
170                 }
171                 ans = 0;
172                 if (buf.cr >= k) ST.find1(u, v, k, 1, n, 1);
173                 else ST.find2(u, v, buf.cl + buf.cr - k + 1, 1, n, 1);
174                 printf("%d
", ans);
175             }
176         }
177     }
178     return 0;
179 }
View Code
原文地址:https://www.cnblogs.com/jklongint/p/4489298.html