首页 > 代码库 > SGU 263. Towers

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\n    pos :%d  cubes :%d  length :%d\n", node, node->size, node->fix, node->pos, node->cubes, node->length);103         printf("    ch[0] :%d ch[1] :%d\n", 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             // notice119             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                     // notice135                     del(T, q->pos);136                 }137             }138         } else {139             r->cubes += c;140         }141         /*142         r = select(1);143         printf(" %d\n", r->length);144         printf("%d\n", 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\n", 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\n", t, r->length);164     }165     void towers() {166         printf("%d towers\n", T ? T->size : 0);167     }168     void cubes() {169         scanf("%d", &t);170         r = select(t);171         printf("%d cubes in %dth tower\n", r->cubes, t);172     }173 } T;174 175 176 char ope[10];177 int main() {178 #ifdef ONLINE_JUDGE179     srand((int)time(NULL));180 #endif181 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