zoukankan      html  css  js  c++  java
  • hdu 3436 Queuejumpers(Splay Tree)

    acm.hdu.edu.cn/showproblem.php?pid=3436

      中等难度的数据结构题,不过数据范围大,所以要hash操作过的数列。1y~

      题意就像题目一样,模拟一队人,其中有人插队,询问某个时刻,第x个人的编号或编号为x的人的位置。

    代码如下:

    View Code
      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <set>
      6 
      7 using namespace std;
      8 
      9 struct Node {
     10     int l, r;
     11     int cnt;
     12     Node *c[2], *p;
     13 
     14     Node (int _cnt = 0, int _l = 0, int _r = -1) {
     15         l = _l;
     16         r = _r;
     17         cnt = _cnt;
     18         c[0] = c[1] = p = NULL;
     19     }
     20 } *Null, *Root, *Head;
     21 
     22 void up(Node *rt) {
     23     rt->cnt = rt->c[0]->cnt + rt->c[1]->cnt + (rt->r - rt->l + 1);
     24 }
     25 
     26 void rotate(Node *x, bool right) {
     27     Node *y = x->p;
     28 
     29     y->c[!right] = x->c[right];
     30     if (x->c[right] != Null) {
     31         x->c[right]->p = y;
     32     }
     33     x->p = y->p;
     34     if (y->p != Null) {
     35         if (y->p->c[0] == y) {
     36             y->p->c[0] = x;
     37         } else {
     38             y->p->c[1] = x;
     39         }
     40     }
     41     x->c[right] = y;
     42     y->p = x;
     43     up(y);
     44 
     45     if (Root == y) Root = x;
     46 }
     47 
     48 void splay(Node *x, Node *f) {
     49     while (x->p != f) {
     50         if (x->p->p == f) {
     51             if (x->p->c[0] == x) rotate(x, 1);
     52             else rotate(x, 0);
     53         } else {
     54             Node *y = x->p, *z = y->p;
     55 
     56             if (z->c[0] == y) {
     57                 if (y->c[0] == x) {
     58                     rotate(y, 1);
     59                     rotate(x, 1);
     60                 } else {
     61                     rotate(x, 0);
     62                     rotate(x, 1);
     63                 }
     64             } else {
     65                 if (y->c[0] == x) {
     66                     rotate(x, 1);
     67                     rotate(x, 0);
     68                 } else {
     69                     rotate(y, 0);
     70                     rotate(x, 0);
     71                 }
     72             }
     73         }
     74     }
     75 
     76     up(x);
     77 }
     78 
     79 const int inf = 0x7f7f7f7f;
     80 
     81 void initSplay() {
     82     Null = new Node();
     83     Root = Head = new Node(1, 0, 0);
     84 
     85     Root->p = Root->c[0] = Null;
     86     Root->c[1] = new Node(1, inf, inf);
     87     Root->c[1]->p = Root;
     88     Root->c[1]->c[0] = Root->c[1]->c[1] = Null;
     89     up(Root);
     90 }
     91 
     92 void in_tra(Node *rt) {
     93     if (rt == Null) {
     94         return ;
     95     }
     96     in_tra(rt->c[0]);
     97     printf("%d %d %d %d %d %d %d\n", rt->l, rt->r, rt->cnt, rt, rt->p, rt->c[0], rt->c[1]);
     98     in_tra(rt->c[1]);
     99 }
    100 
    101 const int maxn = 100005;
    102 const int HASH = 0x55555555;
    103 const int hashMod = 400009;
    104 
    105 char op[maxn][6];
    106 int num[maxn], hash[hashMod], hashPos[hashMod];
    107 
    108 void initHash() {
    109     memset(hashPos, 0, sizeof(hashPos));
    110 }
    111 
    112 void insHash(int x, int pos) {
    113     int p = (x ^ HASH) % hashMod;
    114 
    115     while (hash[p] != x && hashPos[p]) {
    116         p++;
    117         if (p >= hashMod) p -= hashMod;
    118     }
    119 
    120     hash[p] = x;
    121     hashPos[p] = pos;
    122 }
    123 
    124 int getHash(int x) {
    125     int p = (x ^ HASH) % hashMod;
    126 
    127     while (hash[p] != x && hashPos[p]) {
    128         p++;
    129         if (p >= hashMod) p -= hashMod;
    130     }
    131 
    132     return hashPos[p];
    133 }
    134 
    135 Node *rec[maxn << 1];
    136 
    137 void insSplay(Node *x) {
    138     x->c[1] = Root->c[1];
    139     Root->c[1]->p = x;
    140     Root->c[1] = x;
    141     x->p = Root;
    142     x->c[0] = Null;
    143 
    144     splay(x, Null);
    145 }
    146 
    147 void build(int n, int m) {
    148     set<int> used;
    149 
    150     initSplay();
    151     used.clear();
    152     for (int i = 0; i < m; i++) {
    153         scanf("%s%d", op[i], &num[i]);
    154         if (op[i][0] == 'T' || op[i][0] == 'Q') {
    155             used.insert(num[i]);
    156         }
    157     }
    158 
    159     int last = 0, cnt = 0;
    160 
    161     for (set<int>::iterator si = used.begin(); si != used.end(); si++) {
    162 //        printf("%d\n", *si);
    163         if (last + 1 < *si) {
    164             rec[++cnt] = new Node(1, last + 1, *si - 1);
    165 //            printf("add %d %d\n", last + 1, *si - 1);
    166             insSplay(rec[cnt]);
    167         }
    168         rec[++cnt] = new Node(1, *si, *si);
    169 //        printf("add %d\n", *si);
    170         insSplay(rec[cnt]);
    171 
    172         insHash(*si, cnt);
    173         last = *si;
    174     }
    175     if (last < n) {
    176         rec[++cnt] = new Node(1, last + 1, n);
    177 //        printf("add %d %d\n", last + 1, n);
    178         insSplay(rec[cnt]);
    179     }
    180 
    181 //    printf("cnt %d\n", cnt);
    182 //    puts("built!");
    183 }
    184 
    185 int getPos(int x) {
    186     Node *rt = rec[getHash(x)];
    187 
    188     splay(rt, Null);
    189 
    190     return rt->c[0]->cnt;
    191 }
    192 
    193 int getPer(int pos) {
    194     Node *p = Root;
    195 
    196     pos++;
    197     while (true) {
    198         int cnt = p->c[0]->cnt;
    199 
    200         if (cnt + 1 <= pos && pos <= cnt + (p->r - p->l + 1)) {
    201             pos -= cnt;
    202 
    203             return p->l + pos - 1;
    204         } else if (pos <= cnt) {
    205 //            puts("left");
    206             p = p->c[0];
    207         } else {
    208 //            puts("right");
    209             pos -= cnt + (p->r - p->l + 1);
    210             p = p->c[1];
    211         }
    212     }
    213 }
    214 
    215 Node *preNode(Node *x) {
    216     splay(x, Null);
    217     x = x->c[0];
    218     while (x->c[1] != Null) x = x->c[1];
    219 
    220     return x;
    221 }
    222 
    223 Node *postNode(Node *x) {
    224     splay(x, Null);
    225     x = x->c[1];
    226     while (x->c[0] != Null) x = x->c[0];
    227 
    228     return x;
    229 }
    230 
    231 void Top(int x) {
    232     x = getHash(x);
    233 //    printf("x %d\n", x);
    234 
    235     Node *pl = preNode(rec[x]);
    236     Node *pr = postNode(rec[x]);
    237 
    238     splay(pl, Null);
    239     splay(pr, pl);
    240 
    241     // cut node
    242     Node *tmp = pr->c[0];
    243     pr->c[0] = Null;
    244     splay(pr, Null);
    245     // top node
    246     splay(Head, Null);
    247     insSplay(tmp);
    248 }
    249 
    250 void process(int m) {
    251     for (int i = 0; i < m; i++) {
    252         switch (op[i][0]) {
    253             case 'T':
    254 //                puts("Top");
    255                 Top(num[i]);
    256                 break;
    257             case 'Q':
    258 //                puts("Query");
    259                 printf("%d\n", getPos(num[i]));
    260                 break;
    261             case 'R':
    262 //                puts("Rank");
    263                 printf("%d\n", getPer(num[i]));
    264                 break;
    265         }
    266     }
    267 }
    268 
    269 int main() {
    270     int T;
    271 
    272 //    freopen("in", "r", stdin);
    273     scanf("%d", &T);
    274     for (int i = 1; i <= T; i++) {
    275         int n, m;
    276 
    277         scanf("%d%d", &n, &m);
    278         build(n, m);
    279         printf("Case %d:\n", i);
    280         process(m);
    281     }
    282 
    283     return 0;
    284 }

    ——written by Lyon

  • 相关阅读:
    maven mirrorOf
    使用nexus 搭建本地 maven 服务器
    django 访问静态资源
    django 异常问题总结
    django导入 views.py
    vue js 实现 树形菜单
    vue.js 基础
    css之margin
    Vue项目笔记
    eslint ":"号
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_3436_Lyon.html
Copyright © 2011-2022 走看看