[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\n", 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\n", ans);

175             }

176         }

177     }

178     return 0;

179 }
View Code

 

你可能感兴趣的:(HDU)