1503 [NOI2004]郁闷的出纳员

Posted

tags:

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

平衡树裸题。

对于加减操作,可以用lazy-tag思想,对一个标记进行加减。然后添加结点和删除不符合条件结点时考虑一下标记即可。添加薪水为k的结点,就是在平衡树中添加k-tag的结点;删掉薪水小于minwage的结点,就是在平衡树中删除minwage-tag的结点。然后随意玩即可。

我是用treap实现的。

技术分享
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <algorithm>
  4 
  5 using namespace std;
  6 
  7 void Get_Val(int &Ret)
  8 {
  9     Ret = 0;
 10     char ch;
 11     bool Neg(false);
 12     while (ch = getchar(), (ch > 9 || ch < 0) && ch != -)
 13         ;
 14     if (ch == -)
 15     {
 16         Neg = true;
 17         while (ch = getchar(), ch > 9 || ch < 0)
 18             ;
 19     }
 20     do
 21     {
 22         (Ret *= 10) += ch - 0;
 23     }
 24     while (ch = getchar(), ch >= 0 && ch <= 9);
 25     if (Neg)
 26         Ret = -Ret;
 27 }
 28 
 29 int N, Min_Wage;
 30 int Tag;
 31 int Ans_Del;
 32 
 33 struct Treap
 34 {
 35     Treap(const int &v) : v(v), num(1), size(1) {priority = rand(); ch[0] = ch[1] = NULL;}
 36     int priority;
 37     int v;
 38     int num, size;
 39     Treap *ch[2];
 40     inline int cmp(const int &x)
 41     {
 42         return x == v ? -1 : x > v;
 43     }
 44 };
 45 
 46 void pushup(Treap *&o)
 47 {
 48     o -> size = o -> num;
 49     if (o -> ch[0] != NULL)
 50         o -> size += o -> ch[0] -> size;
 51     if (o -> ch[1] != NULL)
 52         o -> size += o -> ch[1] -> size;
 53 }
 54 
 55 void rotate(Treap *&o, const int &d)
 56 {
 57     Treap *k = o -> ch[d ^ 1];
 58     o -> ch[d ^ 1] = k -> ch[d];
 59     k -> ch[d] = o;
 60     pushup(o), pushup(k);
 61     o = k;
 62 }
 63 
 64 void insert(Treap *&o, const int &v)
 65 {
 66     if (o == NULL)
 67         o = new Treap(v);
 68     else
 69     {
 70         int d = o -> cmp(v);
 71         if (d == -1)
 72             ++(o -> num);
 73         else
 74         {
 75             insert(o -> ch[d], v);
 76             if (o -> ch[d] -> priority > o -> priority)
 77                 rotate(o, d ^ 1);
 78         }
 79     }
 80     pushup(o);
 81 }
 82 
 83 void remove(Treap *&o, const int &v) //删掉所有小于v的结点
 84 {
 85     if (o == NULL)
 86         return;
 87     int d = o -> cmp(v);
 88     if (d == -1)
 89     {
 90         Ans_Del += (o -> ch[0] == NULL ? 0 : o -> ch[0] -> size);
 91         o -> ch[0] = NULL;
 92     }
 93     else
 94         if (d == 1)
 95         {
 96             Ans_Del += (o -> ch[0] == NULL ? 0 : o -> ch[0] -> size) + o -> num;
 97             remove(o -> ch[1], v);
 98             o = o -> ch[1];
 99         }
100         else
101             remove(o -> ch[0], v);
102     if (o != NULL)
103         pushup(o);
104 }
105 
106 int kth(Treap *o, const int &k)
107 {
108     if (o == NULL)
109         return 0;
110     int s = o -> ch[1] == NULL ? 0 : o -> ch[1] -> size;
111     if (k > s && k <= s + o -> num)
112         return o -> v;
113     if (k <= s)
114         return kth(o -> ch[1], k);
115     else
116         return kth(o -> ch[0], k - (s + o -> num));
117 }
118 
119 Treap *root;
120 
121 int main()
122 {
123     srand(20160224);
124     root = NULL;
125     char op[2];
126     int k;
127     Get_Val(N), Get_Val(Min_Wage);
128     while (N--)
129     {
130         scanf("%s", op), Get_Val(k);
131         if (*op == I)
132             if (k >= Min_Wage)
133                 insert(root, k - Tag);
134         if (*op == A)
135             Tag += k;
136         if (*op == S)
137         {
138             Tag -= k;
139             remove(root, Min_Wage - Tag);
140         }
141         if (*op == F)
142             if (root == NULL || k > root -> size)
143                 printf("-1\n");
144             else
145                 printf("%d\n", kth(root, k) + Tag);
146     }
147     printf("%d\n", Ans_Del);
148     return 0;
149 }
BZOJ 1503

 

以上是关于1503 [NOI2004]郁闷的出纳员的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1503: [NOI2004]郁闷的出纳员

bzoj 1503: [NOI2004]郁闷的出纳员

bzoj1503: [NOI2004]郁闷的出纳员

bzoj 1503: [NOI2004]郁闷的出纳员 平衡树

Bzoj1503--Noi2004郁闷的出纳员

1503 [NOI2004]郁闷的出纳员