zoukankan      html  css  js  c++  java
  • zoj 2112 Dynamic Rankings(SBT in SegTree)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112

      这题以前我曾经是用k大数DC搜过去的,每次k大前都复制区间,理论上那是必然超时的。今天我用线段树套SBT过了这题,不过其实用树套树做,最后还是要二分结果区间来得到最终的结果,复杂度是O(nlognlogn)。最近看了可持续化数据结构的论文,这题用可持续化线段树可以使代码更简单,内存消耗更小,虽然复杂度貌似没有变。

      这题建立多棵平衡树以后,在使用完以后必须销毁,不然会MLE的!

    代码如下:

    View Code
      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <algorithm>
      4 
      5 using namespace std;
      6 
      7 const int inf = 0x7f7f7f7f;
      8 const int maxn = 50001;
      9 struct SBTNode {
     10     int size, key;
     11     SBTNode *c[2];
     12 
     13     SBTNode(int k = 0) {
     14         key = k;
     15         size = 1;
     16         c[0] = c[1] = NULL;
     17     }
     18 } ;
     19 struct SBTree {
     20     SBTNode *Root;
     21 
     22     SBTree() {
     23         Root = NULL;
     24     }
     25 
     26     void delTreeMain(SBTNode *&rt) {
     27         if (!rt) return ;
     28         delTreeMain(rt->c[0]);
     29         delTreeMain(rt->c[1]);
     30         delete rt;
     31         rt = NULL;
     32     }
     33 
     34     void delTree() {
     35         delTreeMain(Root);
     36     }
     37 
     38     void rotate(SBTNode *&x, bool left) {
     39         bool right = !left;
     40         SBTNode *y = x->c[left];
     41 
     42         x->c[left] = y->c[right];
     43         y->c[right] = x;
     44         y->size = x->size;
     45 
     46         x->size = (x->c[0] ? x->c[0]->size : 0) + (x->c[1] ? x->c[1]->size : 0) + 1;
     47         x = y;
     48     }
     49 
     50     int getPosMain(int key, SBTNode *rt) {
     51         if (!rt) return 0;
     52 
     53         int k = rt->key;
     54 
     55 //        if (key == k) return rt->c[0] ? rt->c[0]->size : 0;
     56         if (key <= k) return getPosMain(key, rt->c[0]);
     57         else return getPosMain(key, rt->c[1]) + (rt->c[0] ? rt->c[0]->size : 0) + 1;
     58     }
     59 
     60     int getPos(int key) {
     61         return getPosMain(key, Root);
     62     }
     63 
     64     void maintain(SBTNode *&rt, bool right) {
     65         if (!rt->c[right] || !rt) return ;
     66 
     67         bool left = !right;
     68         int ls = rt->c[left] ? rt->c[left]->size : 0;
     69 
     70         if (rt->c[right]->c[right] && rt->c[right]->c[right]->size > ls) {
     71             rotate(rt, right);
     72         } else if (rt->c[right]->c[left] && rt->c[right]->c[left]->size > ls) {
     73             rotate(rt->c[right], left);
     74             rotate(rt, right);
     75         } else return ;
     76 
     77         maintain(rt->c[0], false);
     78         maintain(rt->c[1], true);
     79         maintain(rt, false);
     80         maintain(rt, true);
     81     }
     82 
     83     void insMain(SBTNode *&rt, SBTNode *x) {
     84         if (!rt) {
     85             rt = x;
     86             return ;
     87         }
     88         rt->size++;
     89         if (x->key < rt->key) insMain(rt->c[0], x);
     90         else insMain(rt->c[1], x);
     91         maintain(rt, x->key >= rt->key);
     92     }
     93 
     94     void ins(SBTNode *x) {
     95         insMain(Root, x);
     96     }
     97 
     98     void ins(int x) {
     99         SBTNode *tmp = new SBTNode(x);
    100 
    101         insMain(Root, tmp);
    102     }
    103 
    104     void delMain(SBTNode *&rt, int key) {
    105         if (!rt) return ;
    106         rt->size--;
    107         if (key < rt->key) {
    108             delMain(rt->c[0], key);
    109         } else if (key > rt->key) {
    110             delMain(rt->c[1], key);
    111         } else {
    112             SBTNode *t;
    113 
    114             if (!rt->c[0] && !rt->c[1]) {
    115                 delete rt;
    116                 rt = NULL;
    117             } else if (!rt->c[1]) {
    118                 t = rt;
    119                 rt = rt->c[0];
    120                 delete t;
    121             } else if (!rt->c[0]) {
    122                 t = rt;
    123                 rt = rt->c[1];
    124                 delete t;
    125             } else {
    126                 t = rt->c[1];
    127                 while (t->c[0]) t = t->c[0];
    128                 rt->key = t->key;
    129                 delMain(rt->c[1], t->key);
    130             }
    131         }
    132     }
    133 
    134     void del(int k) {
    135         delMain(Root, k);
    136     }
    137 
    138     void printMain(SBTNode *rt) {
    139         if (!rt) return ;
    140         printMain(rt->c[0]);
    141         printf("%d ", rt->key);
    142         printMain(rt->c[1]);
    143     }
    144 
    145     void print() {
    146         printMain(Root);
    147         puts("~~~");
    148     }
    149 } sbt[maxn << 2];
    150 
    151 int rec[maxn];
    152 #define lson l, m, rt << 1
    153 #define rson m + 1, r, rt << 1 | 1
    154 
    155 void build(int l, int r, int rt) {
    156     sbt[rt] = SBTree();
    157     if (l == r) {
    158         return ;
    159     }
    160     int m = (l + r) >> 1;
    161 
    162     build(lson);
    163     build(rson);
    164 }
    165 
    166 void unbuild(int l, int r, int rt) {
    167     sbt[rt].delTree();
    168     if (l == r) {
    169         return ;
    170     }
    171     int m = (l + r) >> 1;
    172 
    173     unbuild(lson);
    174     unbuild(rson);
    175 }
    176 
    177 void ins(int pos, int key, int l, int r, int rt) {
    178     sbt[rt].ins(key);
    179     if (l == r) {
    180         return ;
    181     }
    182     int m = (l + r) >> 1;
    183 
    184     if (pos <= m) {
    185         ins(pos, key, lson);
    186     } else {
    187         ins(pos, key, rson);
    188     }
    189 }
    190 
    191 void repMain(int pos, int key, int l, int r, int rt) {
    192     sbt[rt].del(rec[pos]);
    193     sbt[rt].ins(key);
    194     if (l == r) {
    195         return ;
    196     }
    197     int m = (l + r) >> 1;
    198 
    199     if (pos <= m) {
    200         repMain(pos, key, lson);
    201     } else {
    202         repMain(pos, key, rson);
    203     }
    204 }
    205 
    206 void rep(int pos, int key, int N) {
    207     repMain(pos, key, 1, N, 1);
    208     rec[pos] = key;
    209 }
    210 
    211 int count(int key, int L, int R, int l, int r, int rt) {
    212     if (L <= l && r <= R) {
    213         return sbt[rt].getPos(key);
    214     }
    215     int m = (l + r) >> 1;
    216     int ret = 0;
    217 
    218     if (L <= m) ret += count(key, L, R, lson);
    219     if (m < R) ret += count(key, L, R, rson);
    220 
    221     return ret;
    222 }
    223 
    224 int DC(int L, int R, int N, int k) {
    225     int low = -1, high = 1000000001;
    226     int m;
    227 
    228     while (low + 1 < high) {
    229         m = (low + high) >> 1;
    230         if (count(m, L, R, 1, N, 1) < k) low = m;
    231         else high = m;
    232     }
    233 
    234     return low;
    235 }
    236 
    237 int main() {
    238     int T, n, m;
    239     int a, b, c;
    240     char buf[3];
    241 
    242 //    freopen("in", "r", stdin);
    243     scanf("%d", &T);
    244     while (T--) {
    245         scanf("%d%d", &n, &m);
    246         build(1, n, 1);
    247         for (int i = 1; i <= n; i++) {
    248             scanf("%d", &rec[i]);
    249             ins(i, rec[i], 1, n, 1);
    250         }
    251 //        printf("?? %d\n", count(2, 1, 3, 1, n, 1));
    252         while (m--) {
    253             scanf("%s", buf);
    254             if (buf[0] == 'Q') {
    255                 scanf("%d%d%d", &a, &b, &c);
    256                 printf("%d\n", DC(a, b, n, c));
    257             } else {
    258                 scanf("%d%d", &a, &b);
    259                 rep(a, b, n);
    260             }
    261         }
    262         unbuild(1, n, 1);
    263     }
    264     /**** test SBTree ****
    265         sbt[0] = SBTree();
    266         for (int i = 0; i < 10; i++) {
    267             scanf("%d", &x);
    268             sbt[0].ins(x);
    269     //        sbt[0].print();
    270     //        puts("yeah~");
    271         }
    272         sbt[0].print();
    273         for (int i = 0; i < 5; i++) {
    274             scanf("%d", &x);
    275             printf("%d\n", sbt[0].getPos(x));
    276         }
    277         for (int i = 0; i < 3; i++) {
    278             scanf("%d", &x);
    279             sbt[0].del(x);
    280             sbt[0].print();
    281         }
    282     **********************/
    283 
    284     return 0;
    285 }

    ——written by Lyon

  • 相关阅读:
    redis---01
    mysql优化-----索引覆盖
    mysql优化-------Myisam与innodb引擎,索引文件的区别
    mysql优化-----多列索引的左前缀规则
    mysql---列的选取原则
    boogo08---中间件
    goroutine pool,WaitGroup,chan 示例
    Android开发 |常见的内存泄漏问题及解决办法
    Android中FragmentPagerAdapter对Fragment的缓存(二)
    Android中FragmentPagerAdapter对Fragment的缓存(一)
  • 原文地址:https://www.cnblogs.com/LyonLys/p/zoj_2112_Lyon.html
Copyright © 2011-2022 走看看