NOI 2004 郁闷的出纳员 | Treap

Posted milky-w

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOI 2004 郁闷的出纳员 | Treap相关的知识,希望对你有一定的参考价值。

题目:Luogu 1486

一道平衡树入门题,把员工工资的增减转化成工资下界的增减就可以了。

不过写指针版平衡树的坑很多,注意 maintain( ) 当前节点和调用儿子节点的值前判断是否为 NULL

代码第95行在调用 cur->size 前需判断

  1 #include <cstdio>
  2 #include <string>
  3 #include <cstdlib>
  4 
  5 const int N = 100005;
  6 
  7 int read() {
  8     int x = 0; char c = getchar();
  9     while (!isdigit(c)) c = getchar();
 10     while (isdigit(c)) {
 11         x = (x << 3) + (x << 1) + (c ^ 48);
 12         c = getchar();
 13     } return x;
 14 }
 15 
 16 int low, delt, tot;
 17 
 18 struct Node {
 19     Node *ch[2];
 20     int val, size, num, key;
 21     void in(int x) {
 22         val = x, size = num = 1, key = rand(), ch[0] = ch[1] = NULL;                                                                                 
 23     }
 24     int cmp(int x) {
 25         return x == val ? -1 : x < val ? 0 : 1;
 26     }
 27     void maintain() {
 28         size = num;
 29         if (ch[0]) size += ch[0]->size;
 30         if (ch[1]) size += ch[1]->size;
 31     }
 32 } *root, Pool[N << 1];
 33 
 34 Node *newNode() {
 35     static int cnt = 0;
 36     return &Pool[++cnt];
 37 }
 38 
 39 void rotate(Node *&cur, int d) {
 40     Node *tmp = cur->ch[d ^ 1];
 41     cur->ch[d ^ 1] = tmp->ch[d], tmp->ch[d] = cur;
 42     cur->maintain(), tmp->maintain();
 43     cur = tmp;
 44 }
 45 
 46 void insert(Node *&cur, int val) {
 47     if (!cur) cur = newNode(), cur->in(val);
 48     else {
 49         int d = cur->cmp(val);
 50         if (d == -1) ++cur->num;
 51         else {
 52             insert(cur->ch[d], val);
 53             if (cur->ch[d]->key > cur->key) rotate(cur, d ^ 1);
 54         }
 55         cur->maintain();
 56     }
 57 }
 58 
 59 void remove(Node *&cur) {
 60     if (!cur) return;
 61     if (cur->val >= low) remove(cur->ch[0]);
 62     else {
 63         tot += cur->num + (cur->ch[0] ? cur->ch[0]->size : 0);
 64         cur->ch[0] = NULL;
 65         remove(cur->ch[1]);
 66         cur = cur->ch[1];
 67     }
 68     if (cur) cur->maintain();
 69 }
 70 
 71 int kth(Node *&cur, int k) {
 72     if (!cur) return -1;
 73     int ls = cur->ch[0] ? cur->ch[0]->size : 0;
 74     if (ls + 1 <= k && k <= ls + cur->num) return cur->val;
 75     if (ls >= k) return kth(cur->ch[0], k);
 76     return kth(cur->ch[1], k - ls - cur->num);
 77 }
 78 
 79 int main() {
 80     int n = read(); low = read();
 81     while (n--) {
 82         char opt = getchar();
 83         while (opt != I && opt != A && opt != S && opt != F) opt = getchar();
 84         int x = read();
 85         if (opt == I) {
 86             x += delt;
 87             if (x < low) continue;
 88             insert(root, x);
 89         } else if (opt == A) {
 90             low -= x, delt -= x;
 91         } else if (opt == S) {
 92             low += x, delt += x;
 93             remove(root);
 94         } else {
 95             if (!root || x > root->size) puts("-1");
 96             else {
 97                 x = root->size - x + 1;
 98                 int ans = kth(root, x);
 99                 printf("%d\n", ans - delt);
100             }
101         }
102     }
103     printf("%d\n", tot);
104     return 0;
105 }

 

以上是关于NOI 2004 郁闷的出纳员 | Treap的主要内容,如果未能解决你的问题,请参考以下文章

Noi2004郁闷的出纳员-treap树

[BZOJ1503] [NOI2004] 郁闷的出纳员 (treap)

P1486 [NOI2004] 郁闷的出纳员 FHQ-Treap

P1486 [NOI2004] 郁闷的出纳员 FHQ-Treap

Bzoj1503--Noi2004郁闷的出纳员

NOI2004 郁闷的出纳员