SGU 263. Towers

各种操作:

  1. put x c:表示在第 x 列上增加 c 个积木(c>0)。
  2. tput t x c:表示在塔 t 的第 x 列上增加 c 个积木(c>0)。
  3. towers:询问共有几座塔。
  4. cubes t:询问第 t 座塔共有几个积木。
  5. length t:询问第 t 座塔的长度。
  6. tcubes t x:询问第 t 座塔的第 x 列有几个积木。

对应做法:

  1. towers: 由于要查询tower的数目,以及删除一个tower,加入一个tower,考虑使用平衡树维护。
  2. put: 首先加积木这一件事情只会使得tower发生合并操作对吧,所以可以用并查集维护点属于那个tower。关于合并积木:先查找这个位置是否本来就有积木,如果有,加上就行拉,更新一下BST中的端点的cubes就行拉;否则加上之后插入BST内,如果其左边有towers,或者右边有towers,或者两边都有删除靠右边的节点,将信息传递到左边的节点,然后在并查集内把父亲指向左边节点的左端点,没拉。
  3. tput: 在某个tower内加积木,如果我知道某个tower的左端点,直接加就行了,之后更新BST内节点即可。
  4. cubes: 直接把大小放到tower的最左边的端点中,查询直接输出即可。
  5. lengths: 同上。
  6. tcubes: 同tput。

由于要求支持k大操作,set不适用,只好手写平衡树拉>_<!!。

notice:

  1. 删除节点旋转时要记录方向 int d = t->ch[0]->fix < t->ch[1]->fix; ,千万不要在这里图方便 else rot(t, t->ch[0]->fix < t->ch[1]->fix), del(t->ch[t->ch[0]->fix < t->ch[1]->fix], pos); ,因为已经把儿子转走了,如上定RE。
  2. 新建指针节点一定将其指向NULL,无论之后会不会给它赋值。
  3. 手残打错变量名。。。为什么每次敲数据结构题都会敲错变量名。。。

CODE:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 1e6 + 10;
  4 const int maxp = 1e6;
  5 
  6 int n;
  7 int fa[maxn], num[maxn];
  8 
  9 int test_on;
 10 
 11 int find_fa(int x) {
 12     if(fa[x] != x) fa[x] = find_fa(fa[x]);
 13     return fa[x];
 14 }
 15 
 16 
 17 class BST {
 18 private:
 19     struct treap_node {
 20         treap_node *ch[2];
 21         int fix, size, pos, cubes, length;
 22         treap_node() {
 23             ch[0] = ch[1] = NULL;
 24         }
 25         treap_node(int _pos, int _cubes, int _lengh) {
 26             pos = _pos, cubes = _cubes, length = _lengh;
 27             ch[0] = ch[1] = NULL;
 28             size = 1;
 29             fix = rand();
 30         }
 31     } *T;
 32     void maintain(treap_node *x) {
 33         if(x) {
 34             x->size = 1;
 35             if(x->ch[0]) x->size += x->ch[0]->size;
 36             if(x->ch[1]) x->size += x->ch[1]->size;
 37         }
 38     }
 39     void rot(treap_node *&x, int d) {
 40         treap_node *y = x->ch[d ^ 1];
 41         x->ch[d ^ 1] = y->ch[d];
 42         y->ch[d] = x;
 43         maintain(x), maintain(y);
 44         x = y;
 45     }
 46     void insert(treap_node *&t, int p, int c, int l) {
 47         if(t == NULL) {
 48             t = new treap_node(p, c, l);
 49         } else {
 50             if(p < t->pos) {
 51                 insert(t->ch[0], p, c, l);
 52                 if(t->ch[0]->fix < t->fix) rot(t, 1);
 53             } else {
 54                 insert(t->ch[1], p, c, l);
 55                 if(t->ch[1]->fix < t->fix) rot(t, 0);
 56             }
 57         }
 58         maintain(t);
 59     }
 60     void del(treap_node *&t, int pos) {
 61         if(t->pos == pos) {
 62             if(!(t->ch[0]) || !(t->ch[1])) {
 63                 treap_node *p = t;
 64                 if(t->ch[0]) p = t->ch[0];
 65                 else p = t->ch[1];
 66                 t = NULL;
 67                 delete t;
 68                 t = p;
 69             } else {
 70                 int d = t->ch[0]->fix < t->ch[1]->fix;
 71                 // notice
 72                 rot(t, d);
 73                 del(t->ch[d], pos);
 74             }
 75         } else del(t->ch[t->pos < pos], pos);
 76         if(t) maintain(t);
 77     }
 78     treap_node *select(int k) {
 79         treap_node *t = T;
 80         int size;
 81         while(1) {
 82             size = t->ch[0] ? t->ch[0]->size : 0;
 83             if(k <= size) {
 84                 t = t->ch[0];
 85             } else if(k > size + 1) {
 86                 k -= size + 1;
 87                 t = t->ch[1];
 88             } else break;
 89         }
 90         return t;
 91     }
 92     treap_node *find(treap_node *t, int pos) {
 93         if(t == NULL || t->pos == pos) return t;
 94         return find(t->ch[t->pos < pos], pos);
 95     }
 96 
 97 public:
 98 
 99     void print(treap_node *node) {
100         if(node == NULL) return ;
101         print(node->ch[0]);
102         printf("address :%d  size :%d  fix :%d
    pos :%d  cubes :%d  length :%d
", node, node->size, node->fix, node->pos, node->cubes, node->length);
103         printf("    ch[0] :%d ch[1] :%d
", node->ch[0], node->ch[1]);
104         print(node->ch[1]);
105     }
106 
107     int f, t, x, c;
108     treap_node *r;
109     void put() {
110         scanf("%d%d", &x, &c);
111         f = find_fa(x);
112         num[x] += c;
113         r = find(T, f);
114         if(r == NULL) {
115             insert(T, x, num[x], 1);
116             treap_node *p, *q;
117             p = q = NULL;
118             // notice
119             r = find(T, f);
120             if(0 < x - 1) p = find(T, find_fa(x - 1));
121             if(x + 1 <= maxp) q = find(T, find_fa(x + 1));
122             if(p != NULL || q != NULL) {
123                 if(p != NULL) {
124                     fa[r->pos] = p->pos;
125                     p->cubes += r->cubes;
126                     p->length += r->length;
127                     del(T, r->pos);
128                     r = p;
129                 }
130                 if(q != NULL) {
131                     fa[q->pos] = r->pos;
132                     r->cubes += q->cubes;
133                     r->length += q->length;
134                     // notice
135                     del(T, q->pos);
136                 }
137             }
138         } else {
139             r->cubes += c;
140         }
141         /*
142         r = select(1);
143         printf(" %d
", r->length);
144         printf("%d
", test_on);
145         print(T);
146         puts("");
147         */
148     }
149     void tcubes() {
150         scanf("%d%d", &t, &x);
151         r = select(t);
152         printf("%d cubes in %dth column of %dth tower
", num[r->pos + x - 1], x, t);
153     }
154     void tput() {
155         scanf("%d%d%d", &t, &x, &c);
156         r = select(t);
157         num[r->pos + x - 1] += c;
158         r->cubes += c;
159     }
160     void length() {
161         scanf("%d", &t);
162         r = select(t);
163         printf("length of %dth tower is %d
", t, r->length);
164     }
165     void towers() {
166         printf("%d towers
", T ? T->size : 0);
167     }
168     void cubes() {
169         scanf("%d", &t);
170         r = select(t);
171         printf("%d cubes in %dth tower
", r->cubes, t);
172     }
173 } T;
174 
175 
176 char ope[10];
177 int main() {
178 #ifdef ONLINE_JUDGE
179     srand((int)time(NULL));
180 #endif
181 
182     for(int i = 0; i < maxn; ++i) fa[i] = i;
183     scanf("%d", &n);
184     for(int i = 1; i <= n; ++i) {
185 //        test_on = i;
186 //        printf("%d ", test_on);
187         scanf("%s", ope);
188         if(ope[0] == 'p') {
189             T.put();
190         } else if(ope[0] == 't' && ope[1] == 'o') {
191             T.towers();
192         } else if(ope[0] == 't' && ope[1] == 'p') {
193 //            puts("");
194             T.tput();
195         } else if(ope[0] == 'c') {
196             T.cubes();
197         } else if(ope[0] == 'l') {
198             T.length();
199         } else if(ope[0] == 't' && ope[1] == 'c') {
200             T.tcubes();
201         }
202     }
203 
204     return 0;
205 }
View Code
原文地址:https://www.cnblogs.com/hzf-sbit/p/3900040.html