原題鏈接:http://acdream.info/problem?pid=1738
樹套樹裸題,如下:
如果覺得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