acdream 1738 世风日下的哗啦啦族I

原题链接:http://acdream.info/problem?pid=1738 
树套树裸题,如下:

  1 #include<algorithm>

  2 #include<iostream>

  3 #include<cstdlib>

  4 #include<cstring>

  5 #include<cstdio>

  6 #define lc root<<1

  7 #define rc root<<1|1

  8 using std::sort;

  9 using std::lower_bound;

 10 using std::upper_bound;

 11 const int Max_N = 50010;

 12 const int INF = ~0u >> 1;

 13 struct Node {

 14     int v, s, c;

 15     Node *ch[2];

 16     inline void set(int _v, int _s, Node *p) {

 17         v = _v, s = c = _s;

 18         ch[0] = ch[1] = p;

 19     }

 20     inline void push_up() {

 21         s = ch[0]->s + ch[1]->s + c;

 22     }

 23     inline int cmp(int x) const {

 24         return x == v ? -1 : x > v;

 25     }

 26 };

 27 struct SizeBalanceTree {

 28     int top, ans, tot, sum, arr[Max_N];

 29     Node *null, *tail, stack[Max_N * 18];

 30     Node *store[Max_N << 2], *ptr[Max_N << 2];

 31     inline void init(int n) {

 32         top = 0; 

 33         tail = &stack[0];

 34         null = tail++;

 35         null->set(0, 0, NULL);

 36         for (int i = 1; i <= n; i++) scanf("%d", &arr[i]);

 37         seg_built(1, 1, n);

 38     }

 39     inline Node *newNode(int v) {

 40         Node *p = null;

 41         if (!top) p = tail++;

 42         else p = store[--top];

 43         p->set(v, 1, null);

 44         return p;

 45     }

 46     inline void rotate(Node *&x, int d) {

 47         Node *k = x->ch[!d];

 48         x->ch[!d] = k->ch[d];

 49         k->ch[d] = x;

 50         k->s = x->s;

 51         x->push_up();

 52         x = k;

 53     }

 54     inline void Maintain(Node *&x, int d) {

 55         if (!x->ch[d]->s) return;

 56         if (x->ch[d]->ch[d]->s > x->ch[!d]->s) {

 57             rotate(x, !d);

 58         } else if (x->ch[d]->ch[!d]->s > x->ch[!d]->s) {

 59             rotate(x->ch[d], d), rotate(x, !d);

 60         } else {

 61             return;

 62         }

 63         Maintain(x, 0), Maintain(x, 1);

 64     }

 65     inline void insert(Node *&x, int v) {

 66         if (x == null) {

 67             x = newNode(v);

 68             return;

 69         } else {

 70             x->s++;

 71             int d = x->cmp(v);

 72             if (-1 == d) {

 73                 x->c++;

 74                 return;

 75             }

 76             insert(x->ch[d], v);

 77             x->push_up();

 78             Maintain(x, d);

 79         }

 80     }

 81     inline void del(Node *&x, int v) {

 82         if (!x->s) return;

 83         x->s--;

 84         int d = x->cmp(v);

 85         if (-1 == d) {

 86             if (x->c > 1) {

 87                 x->c--;

 88                 return;

 89             } else if (!x->ch[0]->s || !x->ch[1]->s) {

 90                 store[top++] = x;

 91                 x = x->ch[0]->s ? x->ch[0] : x->ch[1];

 92             } else {

 93                 Node *ret = x->ch[1];

 94                 for (; ret->ch[0]->s; ret = ret->ch[0]);

 95                 del(x->ch[1], x->v = ret->v);

 96             }

 97         } else {

 98             del(x->ch[d], v);

 99         }

100         if (x->s) x->push_up();

101     }

102     inline Node *get_min(Node *x) {

103         for (; x->ch[0]->s; x = x->ch[0]);

104         return x;

105     }

106     inline int find(Node *x, int v) {

107         while (x->s && x->v != v) x = x->ch[v > x->v];

108         return x->c;

109     }

110     inline int count(Node *x, int v) {

111         int res = 0, t = 0;

112         for (; x->s;) {

113             t = x->ch[0]->s;

114             if (v < x->v) x = x->ch[0];

115             else res += t + x->c, x = x->ch[1];

116         }

117         return res;

118     }

119     inline void seg_built(int root, int l, int r) {

120         ptr[root] = null;

121         for (int i = l; i <= r; i++) insert(ptr[root], arr[i]);

122         if (l == r) return;

123         int mid = (l + r) >> 1;

124         seg_built(lc, l, mid);

125         seg_built(rc, mid + 1, r);

126     }

127     inline void seg_modify(int root, int l, int r, int pos, int v){

128         if (pos > r || pos < l) return;

129         del(ptr[root], arr[pos]);

130         insert(ptr[root], v);

131         if (l == r) return;

132         int mid = (l + r) >> 1;

133         seg_modify(lc, l, mid, pos, v);

134         seg_modify(rc, mid + 1, r, pos, v);

135     }

136     inline void seg_query_min(int root, int l, int r, int x, int y) {

137         if (x > r || y < l) return;

138         if (x <= l && y >= r) {

139             Node *ret = get_min(ptr[root]);

140             if (ret->v < ans) ans = ret->v;

141             return;

142         }

143         int mid = (l + r) >> 1;

144         seg_query_min(lc, l, mid, x, y);

145         seg_query_min(rc, mid + 1, r, x, y);

146     }

147     inline void seg_query_tot(int root, int l, int r, int x, int y, int val) {

148         if (x > r || y < l) return;

149         if (x <= l && y >= r) {

150             tot += find(ptr[root], val);

151             return;

152         }

153         int mid = (l + r) >> 1;

154         seg_query_tot(lc, l, mid, x, y, val);

155         seg_query_tot(rc, mid + 1, r, x, y, val);

156     }

157     inline void seg_query_count(int root, int l, int r, int x, int y, int val) {

158         if (x > r || y < l) return;

159         if (x <= l && y >= r) {

160             sum += count(ptr[root], val);   

161             return;

162         }

163         int mid = (l + r) >> 1;

164         seg_query_count(lc, l, mid, x, y, val);

165         seg_query_count(rc, mid + 1, r, x, y, val);

166     }

167     inline void gogo(int n) {

168         int a, b, c, d;

169         scanf("%d", &a);

170         if (1 == a) {

171             scanf("%d %d", &b, &c);

172             seg_modify(1, 1, n, b, c), arr[b] = c;

173         } else if (2 == a) {

174             ans = INF, tot = 0;

175             scanf("%d %d", &b, &c);

176             seg_query_min(1, 1, n, b, c);

177             seg_query_tot(1, 1, n, b, c, ans);

178             printf("%d %d\n", ans, tot);

179         } else {

180             sum = 0;

181             scanf("%d %d %d", &b, &c, &d);

182             seg_query_count(1, 1, n, b, c, d);

183             printf("%d\n", sum);

184         }

185     }

186 }sbt;

187 int main() {

188 #ifdef LOCAL

189     freopen("in.txt", "r", stdin);

190     freopen("out.txt", "w+", stdout);

191 #endif;

192     int n, m;

193     while (~scanf("%d %d", &n, &m)) {

194         sbt.init(n);

195         while (m--) sbt.gogo(n);

196     }

197     return 0;

198 }
View Code

如果觉得sb树跑的慢,再写个红黑树吧。。。

  1 #include<algorithm>

  2 #include<iostream>

  3 #include<cstdlib>

  4 #include<cstring>

  5 #include<cstdio>

  6 #define lc root<<1

  7 #define rc root<<1|1

  8 const int Max_N = 50010;

  9 const int INF = ~0u >> 1;

 10 struct Node {

 11     int data, s, c;

 12     bool color;

 13     Node *fa, *ch[2];

 14     inline void set(int _v, bool _color, int i, Node *p) {

 15         data = _v, color = _color, s = c = i;

 16         fa = ch[0] = ch[1] = p;

 17     }

 18     inline void push_up() {

 19         s = ch[0]->s + ch[1]->s + c;

 20     }

 21     inline void push_down() {

 22         for (Node *x = this; x->s; x = x->fa) x->s--;

 23     }

 24     inline int cmp(int v) const {

 25         return data == v ? -1 : v > data;

 26     }

 27 };

 28 struct RedBlackTree {

 29     int top, ans, tot, sum, arr[Max_N];

 30     Node *null, *tail;

 31     Node stack[Max_N * 18], *store[Max_N << 2], *ptr[Max_N << 2];

 32     inline void init(int n) {

 33         top = 0;

 34         tail = &stack[0];

 35         null = tail++;

 36         null->set(0, 0, 0, NULL);

 37         for (int i = 1; i <= n; i++) scanf("%d", &arr[i]);

 38         seg_built(1, 1, n);

 39     }

 40     inline Node *newNode(int v) {

 41         Node *p = null;

 42         if (!top) p = tail++;

 43         else p = store[--top];

 44         p->set(v, 1, 1, null);

 45         return p;

 46     }

 47     inline void rotate(int root, Node* &x, bool d) {

 48         Node *y = x->ch[!d];

 49         x->ch[!d] = y->ch[d];

 50         if (y->ch[d]->s) y->ch[d]->fa = x;

 51         y->fa = x->fa;

 52         if (!x->fa->s) ptr[root] = y;

 53         else x->fa->ch[x->fa->ch[0] != x] = y;

 54         y->ch[d] = x;

 55         x->fa = y;

 56         y->s = x->s;

 57         x->push_up();

 58     }

 59     inline void insert(int root, int v) {

 60         Node *x = ptr[root], *y = null;

 61         while (x->s) {

 62             x->s++, y = x;

 63             int d = x->cmp(v);

 64             if (-1 == d) {

 65                 x->c++;

 66                 return;

 67             }

 68             x = x->ch[d];

 69         }

 70         x = newNode(v);

 71         if (y->s) y->ch[v > y->data] = x;

 72         else ptr[root] = x;

 73         x->fa = y;

 74         insert_fix(root, x);

 75     }

 76     inline void insert_fix(int root, Node* &x) {

 77         while (x->fa->color) {

 78             Node *par = x->fa, *Gp = par->fa;

 79             bool d = par == Gp->ch[0];

 80             Node *uncle = Gp->ch[d];

 81             if (uncle->color) {

 82                 par->color = uncle->color = 0;

 83                 Gp->color = 1;

 84                 x = Gp;

 85             } else if (x == par->ch[d]) {

 86                 rotate(root, x = par, !d);

 87             } else {

 88                 Gp->color = 1;

 89                 par->color = 0;

 90                 rotate(root, Gp, d);

 91             }

 92         }

 93         ptr[root]->color = 0;

 94     }

 95     inline Node *find(Node *x, int data) {

 96         while (x->s && x->data != data) x = x->ch[x->data < data];

 97         return x;

 98     }

 99     inline void del_fix(int root, Node* &x) {

100         while (x != ptr[root] && !x->color) {

101             bool d = x == x->fa->ch[0];

102             Node *par = x->fa, *sibling = par->ch[d];

103             if (sibling->color) {

104                 sibling->color = 0;

105                 par->color = 1;

106                 rotate(root, x->fa, !d);

107                 sibling = par->ch[d];

108             } else if (!sibling->ch[0]->color && !sibling->ch[1]->color) {

109                 sibling->color = 1, x = par;

110             } else {

111                 if (!sibling->ch[d]->color) {

112                     sibling->ch[!d]->color = 0;

113                     sibling->color = 1;

114                     rotate(root, sibling, d);

115                     sibling = par->ch[d];

116                 }

117                 sibling->color = par->color;

118                 sibling->ch[d]->color = par->color = 0;

119                 rotate(root, par, !d);

120                 break;

121             }

122         }

123         x->color = 0;

124     }

125     inline void del(int root, int data) {

126         Node *z = find(ptr[root], data);

127         if (!z->s) return;

128         if (z->c > 1) {

129             z->c--;

130             z->push_down();

131             return;

132         }

133         Node *y = z, *x = null;

134         if (z->ch[0]->s && z->ch[1]->s) {

135             y = z->ch[1];

136             while (y->ch[0]->s) y = y->ch[0];

137         }

138         x = y->ch[!y->ch[0]->s];

139         x->fa = y->fa;

140         if (!y->fa->s) ptr[root] = x;

141         else y->fa->ch[y->fa->ch[1] == y] = x;

142         if (z != y) z->data = y->data, z->c = y->c;

143         y->fa->push_down();

144         for (Node *k = y->fa; y->c > 1 && k->s && k != z; k = k->fa) k->s -= y->c - 1;

145         if (!y->color) del_fix(root, x);

146         store[top++] = y;

147     }

148     inline Node* get_min(Node *x) {

149         for (; x->ch[0]->s; x = x->ch[0]);

150         return x;

151     }

152     inline int count(Node *x, int v) {

153         int res = 0, t = 0;

154         for (; x->s;) {

155             t = x->ch[0]->s;

156             if (v < x->data) x = x->ch[0];

157             else res += t + x->c, x = x->ch[1];

158         }

159         return res;

160     }

161     inline void seg_built(int root, int l, int r) {

162         ptr[root] = null;

163         for (int i = l; i <= r; i++) insert(root, arr[i]);

164         if (l == r) return;

165         int mid = (l + r) >> 1;

166         seg_built(lc, l, mid);

167         seg_built(rc, mid + 1, r);

168     }

169     inline void seg_modify(int root, int l, int r, int pos, int v){

170         if (pos > r || pos < l) return;

171         del(root, arr[pos]);

172         insert(root, v);

173         if (l == r) return;

174         int mid = (l + r) >> 1;

175         seg_modify(lc, l, mid, pos, v);

176         seg_modify(rc, mid + 1, r, pos, v);

177     }

178     inline void seg_query_min(int root, int l, int r, int x, int y) {

179         if (x > r || y < l) return;

180         if (x <= l && y >= r) {

181             Node *ret = get_min(ptr[root]);

182             if (ret->data < ans) ans = ret->data;

183             return;

184         }

185         int mid = (l + r) >> 1;

186         seg_query_min(lc, l, mid, x, y);

187         seg_query_min(rc, mid + 1, r, x, y);

188     }

189     inline void seg_query_tot(int root, int l, int r, int x, int y, int val) {

190         if (x > r || y < l) return;

191         if (x <= l && y >= r) {

192             tot += find(ptr[root], val)->c;

193             return;

194         }

195         int mid = (l + r) >> 1;

196         seg_query_tot(lc, l, mid, x, y, val);

197         seg_query_tot(rc, mid + 1, r, x, y, val);

198     }

199     inline void seg_query_count(int root, int l, int r, int x, int y, int val) {

200         if (x > r || y < l) return;

201         if (x <= l && y >= r) {

202             sum += count(ptr[root], val);

203             return;

204         }

205         int mid = (l + r) >> 1;

206         seg_query_count(lc, l, mid, x, y, val);

207         seg_query_count(rc, mid + 1, r, x, y, val);

208     }

209     inline void gogo(int n) {

210         int a, b, c, d;

211         scanf("%d", &a);

212         if (1 == a) {

213             scanf("%d %d", &b, &c);

214             seg_modify(1, 1, n, b, c), arr[b] = c;

215         } else if (2 == a) {

216             ans = INF, tot = 0;

217             scanf("%d %d", &b, &c);

218             seg_query_min(1, 1, n, b, c);

219             seg_query_tot(1, 1, n, b, c, ans);

220             printf("%d %d\n", ans, tot);

221         } else {

222             sum = 0;

223             scanf("%d %d %d", &b, &c, &d);

224             seg_query_count(1, 1, n, b, c, d);

225             printf("%d\n", sum);

226         }

227     }

228 }rbt;

229 int main() {

230 #ifdef LOCAL

231     freopen("in.txt", "r", stdin);

232     freopen("out.txt", "w+", stdout);

233 #endif

234     int n, m;

235     while (~scanf("%d %d", &n, &m)) {

236         rbt.init(n);

237         while (m--) rbt.gogo(n);

238     }

239     return 0;

240 }
View Code

 

你可能感兴趣的:(cd)