1. 程式人生 > >NOI 2004 郁悶的出納員 | Treap

NOI 2004 郁悶的出納員 | Treap

del stat pre 出納 節點和 org https return null

題目: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