zoukankan      html  css  js  c++  java
  • Splay Tree (POJ 3580 & UVA 12356 & HDU 1890)

      最近几天熟悉着用Linux,所以做题的量少了下来。这几天新学习了Splay Tree这种数据结构,于是在看懂了Splay操作以后就找了几道题来练手,除了UVA那题是1y顺利通过的,其他两题都出现了各种不同的错误,不过最终还是通过了!

      POJ 3580是我入手Splay Tree的第一道题,这道题需要的操作包括:

      1.区间增加相同的数

      2.区间反转

      3.区间滚动

      4.插入一个数

      5.删除一个数

      6.查询一个区间内的最小值

      我的Splay操作是学习《运用伸展树解决数列维护问题》的论文的,里面教的Splay和Rotate操作包括单纯的和加上更新操作两种。知道了Splay操作以后,延迟操作跟线段树的是一样的,所以不必重新再学。刚学会Splay操作的时候,还不太懂Splay的原理,所以在写insert和delete的时候各种囧态浮现。。。囧!刚开始的时候,我的insert和delete还是很笨重的写了一大串其他平衡树用的insert和delete的方法,出现各种bug以后,我忽而醒觉了,原来Everything is Splay! 这句不知道在哪里听过的话是那么的正确。用Splay Tree就是要将各种操作简化,insert或者delete的时候,只要把要insert和delete的位置Splay出来,剩下要做的事就相当简单了!

    POJ 3580: poj.org/problem?id=3580

    View Code
      1 #define prog 1
      2 
      3 #if prog == 1
      4 
      5 #include <cstdio>
      6 #include <cstdlib>
      7 #include <cstring>
      8 #include <cassert>
      9 #include <algorithm>
     10 
     11 using namespace std;
     12 
     13 const int inf = 0x7f7f7f7f;
     14 
     15 struct Node {
     16     int lateAdd, Min, Data, cnt;
     17     bool Rev;
     18     Node *c[2], *p; // 0 for left child, while 1 for right child
     19 
     20     Node(int _Data = inf, int _cnt = 0) {
     21         Rev = false;
     22         Min = Data = _Data;
     23         lateAdd = 0;
     24         cnt = _cnt;
     25         c[0] = c[1] = p = NULL;
     26     }
     27 } *Null, *Root, *Head, *Tail;
     28 
     29 void up(Node *_x) {
     30     Node *nl = _x->c[0], *nr = _x->c[1];
     31 
     32     _x->Min = min(min(nl->Min, nr->Min), _x->Data);
     33     _x->cnt = nl->cnt + nr->cnt + 1;
     34 }
     35 
     36 void down(Node *_x) {
     37     Node *nl = _x->c[0], *nr = _x->c[1];
     38 
     39     if (_x->Rev) {
     40         if (nl != Null) {
     41             swap(nl->c[0], nl->c[1]);
     42             nl->Rev = !nl->Rev;
     43         }
     44         if (nr != Null) {
     45             swap(nr->c[0], nr->c[1]);
     46             nr->Rev = !nr->Rev;
     47         }
     48         _x->Rev = false;
     49     }
     50     if (_x->lateAdd) {
     51         int late = _x->lateAdd;
     52 
     53         if (nl != Null) {
     54             nl->Min += late;
     55             nl->Data += late;
     56             nl->lateAdd += late;
     57         }
     58         if (nr != Null) {
     59             nr->Min += late;
     60             nr->Data += late;
     61             nr->lateAdd += late;
     62         }
     63         _x->lateAdd = 0;
     64     }
     65 }
     66 
     67 void traverse(Node *rt) {
     68     if (rt == Null) {
     69         return ;
     70     }
     71     down(rt);
     72     printf("rt %d  p %d  ls %d  rs %d  data %d  min %d cnt %d\n", rt, rt->p, rt->c[0], rt->c[1], rt->Data, rt->Min, rt->cnt);
     73     traverse(rt->c[0]);
     74     traverse(rt->c[1]);
     75 }
     76 
     77 void in_tra(Node *rt) {
     78     if (rt == Null) {
     79         return ;
     80     }
     81     down(rt);
     82     in_tra(rt->c[0]);
     83     if (rt ->Data != inf) printf("%d ", rt->Data);
     84     in_tra(rt->c[1]);
     85     up(rt);
     86 }
     87 
     88 void Rotate(Node *_x, bool right) { // false for left rotate, while true for right rotate
     89     Node *_y = _x->p;
     90     bool left = !right;
     91 
     92     down(_y);
     93     down(_x);
     94     _y->c[left] = _x->c[right];
     95 
     96     if (_x->c[right] != Null) _x->c[right]->p = _y;
     97     _x->p = _y->p;
     98     if (_y->p != Null) {
     99         if (_y->p->c[0] == _y) {
    100             _y->p->c[0] = _x;
    101         } else {
    102             _y->p->c[1] = _x;
    103         }
    104     }
    105 
    106     _x->c[right] = _y;
    107     _y->p = _x;
    108     if (_y == Root) Root = _x;
    109 
    110     up(_y);
    111 }
    112 
    113 void Splay(Node *_x, Node *_f) {// splay _x to the node under _f
    114     down(_x);
    115     while (_x->p != _f) {
    116         if (_x->p->p == _f) {
    117             if (_x->p->c[0] == _x) {
    118                 Rotate(_x, 1);
    119             } else {
    120                 Rotate(_x, 0);
    121             }
    122         } else {
    123             Node *_y = _x->p, *_z = _y->p;
    124 
    125             if (_z->c[0] == _y) {
    126                 if (_y->c[0] == _x) {
    127                     Rotate(_y, 1);
    128                     Rotate(_x, 1);
    129                 } else {
    130                     Rotate(_x, 0);
    131                     Rotate(_x, 1);
    132                 }
    133             } else {
    134                 if (_y->c[0] == _x) {
    135                     Rotate(_x, 1);
    136                     Rotate(_x, 0);
    137                 } else {
    138                     Rotate(_y, 0);
    139                     Rotate(_x, 0);
    140                 }
    141             }
    142         }
    143     }
    144 
    145     up(_x);
    146 }
    147 
    148 Node *getPos(int pos) {
    149     Node *p = Root;
    150 
    151     // find position
    152     pos++;
    153     while (true) {
    154         down(p);
    155 
    156         int cnt = p->c[0]->cnt;
    157 
    158         if (pos == cnt + 1) {
    159             break;
    160         } else if (pos <= cnt) {
    161             p = p->c[0];
    162         } else {
    163             pos -= cnt + 1;
    164             p = p->c[1];
    165         }
    166     }
    167 
    168     return p;
    169 }
    170 
    171 void insPos(int elem, int pos) {
    172     Node *pl = getPos(pos), *pr = getPos(pos + 1);
    173     Node *tmp = new Node(elem, 1);
    174 
    175     // insert node
    176     Splay(pl, Null);
    177     Splay(pr, pl);
    178     pr->c[0] = tmp;
    179     tmp->p = pr;
    180     tmp->c[0] = tmp->c[1] = Null;
    181 
    182     Splay(tmp, Null);
    183 }
    184 
    185 void delPos(int pos) {
    186     Node *pl = getPos(pos - 1), *pr = getPos(pos + 1);
    187     Node *p;
    188 
    189     Splay(pl, Null);
    190     Splay(pr, pl);
    191     p = pr->c[0];
    192     pr->c[0] = Null;
    193 
    194     delete p;
    195     Splay(pr, Null);
    196 }
    197 
    198 void init() {
    199     Null = new Node();
    200     Head = Root = new Node(inf, 2);
    201     Tail = new Node(inf, 1);
    202 
    203     Root->c[1] = Tail;
    204     Root->c[0] = Root->p = Null;
    205     Tail->p = Root;
    206     Tail->c[0] = Tail->c[1] = Null;
    207 }
    208 
    209 void input(int n) {
    210     int x;
    211 
    212     for (int i = 0; i < n; i++) {
    213         scanf("%d", &x);
    214         insPos(x, i);
    215     }
    216 }
    217 
    218 void reverse(int l, int r) {
    219     if (l == r) return ;
    220     Node *pl = getPos(l - 1), *pr = getPos(r + 1);
    221 
    222     // get segment
    223     Splay(pl, Null);
    224     Splay(pr, pl);
    225 
    226     pr = pr->c[0];
    227     swap(pr->c[0], pr->c[1]);
    228     pr->Rev = true;
    229 
    230     Splay(pr, Null);
    231 }
    232 
    233 void revolve(int l, int r, int t) {
    234     t %= (r - l + 1);
    235     if (l == r || t == 0) return ;
    236 
    237     Node *pl = getPos(r - t), *pr = getPos(r + 1);
    238 
    239 //    printf("%d %d %d %d %d\n", pl, pr, l, r, t);
    240 
    241     // get segment
    242     Splay(pl, Null);
    243     Splay(pr, pl);
    244 
    245     // cut down segment
    246     Node *tmp = pr->c[0];
    247 
    248     pr->c[0] = Null;
    249     Splay(pr, Null);
    250 
    251     // insert segment
    252     pl = getPos(l - 1);
    253     pr = getPos(l);
    254     Splay(pl, Null);
    255     Splay(pr, pl);
    256 
    257     pr->c[0] = tmp;
    258     tmp->p = pr;
    259     Splay(tmp, Null);
    260 }
    261 
    262 void add(int l, int r, int d) {
    263     Node *pl = getPos(l - 1), *pr = getPos(r + 1);
    264 
    265 //    printf("%d %d   %d %d\n", pl, pr, l, r);
    266     Splay(pl, Null);
    267     Splay(pr, pl);
    268 
    269     pr = pr->c[0];
    270     down(pr);
    271     pr->lateAdd += d;
    272     pr->Data += d;
    273     pr->Min += d;
    274     Splay(pr, Null);
    275 }
    276 
    277 int getMin(int l, int r) {
    278     Node *pl = getPos(l - 1), *pr = getPos(r + 1);
    279 
    280     Splay(pl, Null);
    281     Splay(pr, pl);
    282     pr = pr->c[0];
    283     down(pr);
    284 
    285     return pr->Min;
    286 }
    287 
    288 int main() {
    289     int n;
    290 //    int cnt = 0;
    291 
    292 //    freopen("in", "r", stdin);
    293 //    freopen("out", "w", stdout);
    294 
    295     while (~scanf("%d", &n)) {
    296 //        printf("cnt %d\n", ++cnt);
    297         init();
    298         input(n);
    299 //        puts("Input success!");
    300 //        puts("~~~");
    301 //        traverse(Root);
    302 //        puts("!!!");
    303         scanf("%d", &n);
    304 //        in_tra(Root);
    305 //        printf("~~~cnt %d\n", Root->cnt - 2);
    306         for (int i = 1; i <= n; i++) {
    307             char buf[10];
    308             int l, r, d ;
    309 
    310             scanf("%s", buf);
    311             if (!strcmp(buf, "ADD")) {
    312                 scanf("%d%d%d", &l, &r, &d);
    313                 if (l > r) swap(l, r);
    314                 add(l, r, d);
    315             } else if (!strcmp(buf, "REVERSE")) {
    316                 scanf("%d%d", &l, &r);
    317                 if (l > r) swap(l, r);
    318                 reverse(l, r);
    319             } else if (!strcmp(buf, "REVOLVE")) {
    320                 scanf("%d%d%d", &l, &r, &d);
    321                 if (l > r) swap(l, r);
    322                 revolve(l, r, d);
    323             } else if (!strcmp(buf, "INSERT")) {
    324                 scanf("%d%d", &l, &r);
    325                 insPos(r, l);
    326             } else if (!strcmp(buf, "DELETE")) {
    327                 scanf("%d", &l);
    328                 delPos(l);
    329             } else {
    330                 scanf("%d%d", &l, &r);
    331                 if (l > r) swap(l, r);
    332                 printf("%d\n", getMin(l, r));
    333             }
    334 
    335 //            printf("op %d %s\n", i, buf);
    336 //            in_tra(Root);
    337 //            printf("~~~cnt %d\n", Root->cnt - 2);
    338 
    339 //            puts("~~~~~~~~~~~~~");
    340 //            traverse(Root);
    341 //            puts("!!!!!!!!!!!!!");
    342         }
    343     }
    344 
    345     return 0;
    346 }
    347 
    348 #endif
    349 
    350 #if prog == 2
    351 
    352 #include <cstdio>
    353 #include <cstring>
    354 #include <algorithm>
    355 
    356 using namespace std;
    357 
    358 const int maxn = 10000;
    359 int a[maxn], ttLen;
    360 
    361 void input(int n) {
    362     ttLen = n;
    363     for (int i = 1; i <= n; i++) {
    364         scanf("%d", &a[i]);
    365     }
    366 }
    367 
    368 void add(int l, int r, int d) {
    369     for (int i = l; i <= r; i++) {
    370         a[i] += d;
    371     }
    372 }
    373 
    374 void revolve(int l, int r, int t) {
    375     t %= (r - l + 1);
    376     if (r == l || t == 0) return ;
    377 
    378     int buf[maxn];
    379 
    380     for (int i = l; i <= r; i++) {
    381         buf[i - l] = a[i];
    382     }
    383     for (int i = 0; i <= r - l; i++) {
    384         a[(i + t) % (r - l + 1) + l] = buf[i];
    385     }
    386 }
    387 
    388 void insPos(int elem, int pos) {
    389     int p = ttLen;
    390 
    391     while (p > pos) {
    392         a[p + 1] = a[p];
    393         p--;
    394     }
    395     a[pos + 1] = elem;
    396     ttLen++;
    397 }
    398 
    399 void delPos(int pos) {
    400     int p = pos;
    401 
    402     while (p < ttLen) {
    403         a[p] = a[p + 1];
    404         p++;
    405     }
    406     ttLen--;
    407 }
    408 
    409 int getMin(int l, int r) {
    410     int ret = 0x7f7f7f7f;
    411 
    412     for (int i = l; i <= r; i++) {
    413         ret = min(ret, a[i]);
    414     }
    415 
    416     return ret;
    417 }
    418 
    419 int main() {
    420     int n;
    421 
    422     freopen("in", "r", stdin);
    423     freopen("cmp", "w", stdout);
    424 
    425     while (~scanf("%d", &n)) {
    426         input(n);
    427 
    428         scanf("%d", &n);
    429         for (int i = 1; i <= ttLen; i++) printf("%d ", a[i]);
    430         printf("~~~cnt %d\n", ttLen);
    431         for (int i = 1; i <= n; i++) {
    432             char buf[10];
    433             int l, r, d ;
    434 
    435             scanf("%s", buf);
    436             if (!strcmp(buf, "ADD")) {
    437                 scanf("%d%d%d", &l, &r, &d);
    438                 if (l > r) swap(l, r);
    439                 add(l, r, d);
    440             } else if (!strcmp(buf, "REVERSE")) {
    441                 scanf("%d%d", &l, &r);
    442                 if (l > r) swap(l, r);
    443                 reverse(a + l, a + r + 1);
    444             } else if (!strcmp(buf, "REVOLVE")) {
    445                 scanf("%d%d%d", &l, &r, &d);
    446                 if (l > r) swap(l, r);
    447                 revolve(l, r, d);
    448             } else if (!strcmp(buf, "INSERT")) {
    449                 scanf("%d%d", &l, &r);
    450                 insPos(r, l);
    451             } else if (!strcmp(buf, "DELETE")) {
    452                 scanf("%d", &l);
    453                 delPos(l);
    454             } else {
    455                 scanf("%d%d", &l, &r);
    456                 if (l > r) swap(l, r);
    457                 printf("%d\n", getMin(l, r));
    458             }
    459 
    460 //            printf("op %d %s\n", i, buf);
    461 //            for (int j = 1; j <= ttLen; j++) printf("%d ", a[j]);
    462 //            printf("~~~cnt %d\n", ttLen);
    463 
    464         }
    465     }
    466 
    467     return 0;
    468 }
    469 
    470 #endif

      下面这是昨晚训练的一道题,刚开始的时候我直接就想到了Segment Tree,可是想到这题用Segment Tree解决的代码难度相对用Splay Tree会大不少,所以我就想到了用昨天懂的Splay Tree来完成,虽然中间出现一点小问题,不过最后还是1y通过了!

      题意是初始化一个1到n的序列,每个操作将删除指定的区间,并且返回区间两端最接近的未被删除的点的位置,如果没有就返回星号。用Splay Tree方便就是方便在删除区间的同时就找到了要输出的两个值。查找端点的时候,先找到最接近区间端点的值的结点,然后利用Splay操作,把该结点旋转至根,这样可以相当方便的找到前驱和后继。删除区间就是删除被夹逼出来的一个子树。这题给了一秒的时间,刚开始评估复杂度的时候因为Splay操作常数大,觉得可能会超时,结果不到500ms就得到结果了!

    UVA 12356: uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3778

    View Code
      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <stack>
      6 #include <vector>
      7 #include <cmath>
      8 
      9 using namespace std;
     10 int inf = 0x7f7f7f7f;
     11 
     12 struct Node {
     13     int key, cnt;
     14     int p, c[2];
     15 
     16     void init(int _key, int _cnt) {
     17         key = _key;
     18         cnt = _cnt;
     19         p = c[0] = c[1] = 0;
     20     }
     21 } node[100010];
     22 int Null, Root, cntNode;
     23 
     24 void up(int rt) {
     25     node[rt].cnt = node[node[rt].c[0]].cnt + node[node[rt].c[1]].cnt + 1;
     26 }
     27 
     28 void rotate(int x, bool right) {
     29     int y = node[x].p;
     30     bool left = !right;
     31 
     32     node[y].c[left] = node[x].c[right];
     33     if (node[x].c[right] != Null) node[node[x].c[right]].p = y;
     34     node[x].p = node[y].p;
     35     if (node[y].p != Null) {
     36         if (node[node[y].p].c[false] == y) node[node[y].p].c[false] = x;
     37         else node[node[y].p].c[true] = x;
     38     }
     39     node[x].c[right] = y;
     40     node[y].p = x;
     41 
     42     if (y == Root) Root = x;
     43     up(x);
     44 }
     45 
     46 void splay(int x, int f) {
     47     while (node[x].p != f) {
     48         if (node[node[x].p].p == f) {
     49             if (node[node[x].p].c[0] == x) {
     50                 rotate(x, true);
     51             } else {
     52                 rotate(x, false);
     53             }
     54         } else {
     55             int y = node[x].p, z = node[y].p;
     56 
     57             if (node[z].c[false] == y) {
     58                 if (node[y].c[false] == x) {
     59                     rotate(y, true);
     60                     rotate(x, true);
     61                 } else {
     62                     rotate(x, false);
     63                     rotate(x, true);
     64                 }
     65             } else {
     66                 if (node[y].c[false] == x) {
     67                     rotate(x, true);
     68                     rotate(x, false);
     69                 } else {
     70                     rotate(y, false);
     71                     rotate(x, false);
     72                 }
     73             }
     74         }
     75     }
     76     up(x);
     77 }
     78 
     79 void init() {
     80     Null = 0;
     81     node[Null].init(inf, 0);
     82     Root = cntNode = 1;
     83 
     84     node[Root].init(-inf, 1);
     85     cntNode++;
     86     node[Root].c[1] = cntNode;
     87     node[cntNode].init(inf, 1);
     88     node[cntNode].p = Root;
     89 }
     90 
     91 int find(int key, bool right) {
     92     int p = Root;
     93 
     94     while (true) {
     95         if (node[p].key == key) break;
     96         else if (node[p].key < key) {
     97             if (node[p].c[1] == Null) break;
     98             p = node[p].c[1];
     99         } else {
    100             if (node[p].c[0] == Null) break;
    101             p = node[p].c[0];
    102         }
    103     }
    104     if (right) {
    105         if (node[p].key <= key) {
    106             splay(p, Null);
    107             while (node[p].key <= key) p = node[p].c[1];
    108             while (node[p].c[0] != Null && node[node[p].c[0]].key >= key) p = node[p].c[0];
    109         }
    110         return p;
    111     } else {
    112         if (node[p].key >= key) {
    113             splay(p, Null);
    114             while (node[p].key >= key) p = node[p].c[0];
    115             while (node[p].c[1] != Null && node[node[p].c[1]].key <= key) p = node[p].c[1];
    116         }
    117         return p;
    118     }
    119 }
    120 
    121 void delSeg(int &l, int &r){
    122     l = find(l, false);
    123 //    puts("~~~");
    124     r = find(r, true);
    125 //    puts("!!!");
    126 //    printf("%d %d\n", l, r);
    127 //    printf("%d %d\n", node[l].key, node[r].key);
    128     splay(l, Null);
    129     splay(r, l);
    130     node[r].c[0] = Null;
    131 }
    132 
    133 void build(int n) {
    134     init();
    135     for (int i = 1; i <= n; i++) {
    136         cntNode++;
    137         node[cntNode].init(i, 1);
    138         node[cntNode].c[1] = node[Root].c[1];
    139         node[node[Root].c[1]].p = cntNode;
    140         node[Root].c[1] = cntNode;
    141         node[cntNode].p = Root;
    142 
    143         splay(cntNode, Null);
    144     }
    145 }
    146 
    147 void in_tra(int rt) {
    148     if (rt == Null) return ;
    149     in_tra(node[rt].c[0]);
    150     printf("%d ", node[rt].key);
    151     in_tra(node[rt].c[1]);
    152 }
    153 
    154 int main() {
    155 //    freopen("in", "r", stdin);
    156 //    freopen("out", "w", stdout);
    157 
    158     int n, m;
    159 
    160     while (~scanf("%d%d", &n, &m) && (n + m)) {
    161         build(n);
    162         while (m--) {
    163             int l, r;
    164 
    165             scanf("%d%d", &l, &r);
    166             delSeg(l, r);
    167             if (node[l].key == -inf) putchar('*');
    168             else printf("%d", node[l].key);
    169             putchar(' ');
    170             if (node[r].key == inf) putchar('*');
    171             else printf("%d", node[r].key);
    172             puts("");
    173         }
    174         puts("-");
    175     }
    176 
    177     return 0;
    178 }

      下面这题也是是比较简单的,只用到了反转操作,不过数列不是一个单纯的排列,所以要先处理出稳定排序后的结果,重新附上标号以后就可以直接模拟了!

    HDU 1890: acm.hdu.edu.cn/showproblem.php?pid=1890

    View Code
      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <algorithm>
      5 
      6 using namespace std;
      7 
      8 const int inf = 0x7f7f7f7f;
      9 struct Node {
     10     int cnt;
     11     bool rev;
     12     Node *c[2], *p;
     13 
     14     Node(int _cnt = 0) {
     15         cnt = _cnt;
     16         rev = false;
     17         c[0] = c[1] = p = NULL;
     18     }
     19 } *Null, *Root;
     20 
     21 void up(Node *rt) {
     22     rt->cnt = rt->c[0]->cnt + rt->c[1]->cnt + 1;
     23 }
     24 
     25 void init() {
     26     Null = new Node();
     27     Root = new Node(1);
     28 
     29     Root->c[0] = Root->p = Null;
     30     Root->c[1] = new Node(1);
     31     Root->c[1]->p = Root;
     32     Root->c[1]->c[0] = Root->c[1]->c[1] = Null;
     33     up(Root);
     34 }
     35 
     36 void down(Node *rt) {
     37     Node *ls = rt->c[0], *rs = rt->c[1];
     38 
     39     if (rt->rev) {
     40         if (ls != Null) {
     41             swap(ls->c[0], ls->c[1]);
     42             ls->rev = !ls->rev;
     43         }
     44         if (rs != Null) {
     45             swap(rs->c[0], rs->c[1]);
     46             rs->rev = !rs->rev;
     47         }
     48         rt->rev = false;
     49     }
     50 }
     51 
     52 void rotate(Node *x, bool right) {
     53     Node *y = x->p;
     54     bool left = !right;
     55 
     56     down(y);
     57     down(x);
     58     y->c[left] = x->c[right];
     59     if (x->c[right] != Null) {
     60         x->c[right]->p = y;
     61     }
     62     x->p = y->p;
     63     if (y->p != Null) {
     64         if (y->p->c[0] == y) {
     65             y->p->c[0] = x;
     66         } else {
     67             y->p->c[1] = x;
     68         }
     69     }
     70     x->c[right] = y;
     71     y->p = x;
     72 
     73     up(y);
     74     if (y == Root) Root = x;
     75 }
     76 
     77 void splay(Node *x, Node *f) {
     78     down(x);
     79 
     80     while (x->p != f) {
     81         if (x->p->p == f) {
     82             if (x->p->c[0] == x) {
     83                 rotate(x, true);
     84             } else {
     85                 rotate(x, false);
     86             }
     87         } else {
     88             Node *y = x->p, *z = y->p;
     89 
     90             if (z->c[0] == y) {
     91                 if (y->c[0] == x) {
     92                     rotate(y, true);
     93                     rotate(x, true);
     94                 } else {
     95                     rotate(x, false);
     96                     rotate(x, true);
     97                 }
     98             } else {
     99                 if (y->c[0] == x) {
    100                     rotate(x, true);
    101                     rotate(x, false);
    102                 } else {
    103                     rotate(y, false);
    104                     rotate(x, false);
    105                 }
    106             }
    107         }
    108     }
    109 
    110     up(x);
    111 }
    112 
    113 const int maxn = 100005;
    114 struct List {
    115     int data;
    116     int pri;
    117 } list[maxn];
    118 Node *rec[maxn];
    119 
    120 bool cmp1(List _a, List _b) {
    121     if (_a.data != _b.data) return _a.data < _b.data;
    122     return _a.pri < _b.pri;
    123 }
    124 
    125 bool cmp2(List _a, List _b) {
    126     return _a.pri < _b.pri;
    127 }
    128 
    129 Node *getNode(int pos) {
    130     Node *p = Root;
    131 
    132     pos++;
    133     while (true) {
    134         down(p);
    135 
    136         int c = p->c[0]->cnt;
    137 
    138         if (pos == c + 1) {
    139             return p;
    140         } else if (pos <= c) {
    141             p = p->c[0];
    142         } else {
    143             pos -= c + 1;
    144             p = p->c[1];
    145         }
    146     }
    147 }
    148 
    149 void insPos(int data, int pos) {
    150     Node *pl = getNode(pos), *pr = getNode(pos + 1);
    151 
    152     splay(pl, Null);
    153     splay(pr, pl);
    154 
    155     Node *tmp = new Node(1);
    156 
    157     down(pr);
    158     rec[data] = tmp;
    159     pr->c[0] = tmp;
    160     tmp->p = pr;
    161     tmp->c[0] = tmp->c[1] = Null;
    162 
    163     splay(tmp, Null);
    164 }
    165 
    166 int getPos(Node *x) {
    167     splay(x, Null);
    168 
    169     return x->c[0]->cnt;
    170 }
    171 
    172 void reverse(int n) {
    173     Node *pl = getNode(n), *pr = getNode(getPos(rec[n]) + 1);
    174 
    175     if (pl->c[1] == rec[n]) return ;
    176     splay(pl, Null);
    177     splay(pr, pl);
    178 
    179     pr = pr->c[0];
    180     down(pr);
    181     pr->rev = !pr->rev;
    182     swap(pr->c[0], pr->c[1]);
    183 
    184     splay(pr, Null);
    185 }
    186 
    187 void in_tra(Node *rt) {
    188     if (rt == Null) {
    189         return ;
    190     }
    191     down(rt);
    192     in_tra(rt->c[0]);
    193     printf("%d %d %d p %d\n", rt, rt->c[0], rt->c[1], rt->p);
    194     in_tra(rt->c[1]);
    195 }
    196 
    197 void pre(int n) {
    198     sort(list, list + n, cmp1);
    199     for (int i = 0; i < n; i++) {
    200         list[i].data = i;
    201     }
    202     sort(list, list + n, cmp2);
    203     for (int i = 0; i < n; i++) {
    204         insPos(list[i].data, i);
    205     }
    206 }
    207 
    208 void build(int n) {
    209     init();
    210     for (int i = 0, x; i < n; i++) {
    211         scanf("%d", &x);
    212         list[i].data = x;
    213         list[i].pri = i;
    214     }
    215     pre(n);
    216 }
    217 
    218 void deal(int n) {
    219 //    in_tra(Root);
    220 //    puts("~~~");
    221 //    for (int i = 0; i < n; i++) {
    222 //        printf("%d %d\n", i, rec[i]);
    223 //    }
    224 //    printf("%d\n", n);
    225     for (int i = 0; i < n; i++) {
    226         if (i) putchar(' ');
    227         printf("%d", getPos(rec[i]));
    228         reverse(i);
    229     }
    230     puts("");
    231 }
    232 
    233 int main() {
    234     int n;
    235 
    236 //    freopen("in", "r", stdin);
    237 //    freopen("out", "w", stdout);
    238     while (~scanf("%d", &n) && n) {
    239         build(n);
    240         deal(n);
    241     }
    242 
    243     return 0;
    244 }

      做这几题Splay Tree,暂时没遇到比较难的操作,不过Splay Tree的代码都有一定的长度的啊!如果没打好,debug起来是挺吃力的。。。囧!

      另外,除了中间那题,其余两题都是用动态内存处理的!

    ——written by Lyon

  • 相关阅读:
    prase arraylist where in to ParamsQuery on sql server 2008 using TVB: tvpdemo.cs(where in 转sql 参数化查询)
    手动依赖性注入 NInject(1) (转载)
    单件(单态,Singleton)模式部分
    详解Javascript中的Url编码/解码
    学习Web应用漏洞最好的教程WebGoat(转载)
    百度网盘 邀请码
    colorbox去除close关闭按钮,附上colorbox的基本使用方法
    P3974 [TJOI2015]组合数学
    P1772 [ZJOI2006]物流运输
    P1434 [SHOI2002]滑雪
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_3580_UVA_12356_HDU_1890_Lyon.html
Copyright © 2011-2022 走看看