bzoj1503: [NOI2004]郁闷的出纳员

地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1503

题目:

1503: [NOI2004]郁闷的出纳员

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 12285  Solved: 4389
[Submit][Status][Discuss]

Description

OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?

Input

Output

输出文件的行数为F命令的条数加一。对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。输出文件的最后一行包含一个整数,为离开公司的员工的总数。

Sample Input

9 10
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2

Sample Output

10
20
-1
2

HINT

 

I命令的条数不超过100000 A命令和S命令的总条数不超过100 F命令的条数不超过100000 每次工资调整的调整量不超过1000 新员工的工资不超过100000

 
思路:
  恩,傻逼题一个,模板改了好久。。。
  
  1 /**************************************************************
  2     Problem: 1503
  3     User: weeping
  4     Language: C++
  5     Result: Accepted
  6     Time:1252 ms
  7     Memory:5324 kb
  8 ****************************************************************/
  9  
 10 #include <bits/stdc++.h>
 11  
 12 using namespace std;
 13  
 14 #define lc ch[x][0]
 15 #define rc ch[x][1]
 16  
 17 struct SplayTree
 18 {
 19  
 20     const static int maxn = 1e5 + 15;
 21  
 22     int tot,root,ch[maxn][2], key[maxn], val[maxn], sz[maxn], rev[maxn], fa[maxn];
 23     int cnt;
 24  
 25     inline void init( int x, int ky, int v = 0, int par = 0 )
 26     {
 27         lc=rc=0, fa[x]= par, key[x] = ky, val[x] = v, sz[x] = 1, rev[x] = 0;
 28     }
 29  
 30     inline void init()
 31     {
 32         init( 0, 0, 0 );
 33         sz[0] = 0;
 34         cnt = tot = root = 0 ;
 35     }
 36  
 37     inline void push_up(int x)
 38     {
 39         sz[x] = sz[lc] + sz[rc] + 1;
 40     }
 41  
 42     inline void reverse(int x)
 43     {
 44         rev[x] ^= 1, swap( lc, rc);
 45     }
 46  
 47     inline void push_down(int x)
 48     {
 49         if(rev[x])
 50         {
 51             if(lc)  reverse(lc);
 52             if(rc)  reverse(rc);
 53             rev[x] = 0;
 54         }
 55     }
 56  
 57     void rotate( int x)
 58     {
 59         int f = fa[x], gf = fa[f];
 60         int t1 = (ch[f][1] == x), t2 = (ch[gf][1] == f);
 61         if( gf ) ch[gf][t2] = x;
 62         fa[x] = gf, ch[f][t1] = ch[x][1^t1], fa[ch[f][t1]] = f;
 63         ch[x][t1^1] = f, fa[f] = x;
 64         push_up( f ), push_up( x );
 65     }
 66  
 67     void splay( int x, int tar )
 68     {
 69         for(int f = fa[x], gf = fa[f]; f != tar; rotate(x), f = fa[x], gf = fa[f])
 70         if(gf != tar)
 71             rotate( ((ch[f][1] == x) == (ch[gf][1] == f) )? f: x);
 72         if( !tar ) root = x;
 73     }
 74  
 75     void insert( int ky, int v)
 76     {
 77         int x = root, ls = root;
 78         while(x)
 79         {
 80             push_down(x);
 81             sz[x] ++, ls = x;
 82             x = ch[x][ky > key[x]];
 83         }
 84         init( ++tot, ky, v, ls);
 85         ch[ls][ky > key[ls]] = tot;
 86         splay( tot, 0);
 87     }
 88  
 89     int find( int ky)
 90     {
 91         //debug(root);printf("\n");
 92         int x = root;
 93         while(x)
 94         {
 95             push_down(x);
 96             if(key[x] > ky) x = lc;
 97             else if(rc && key[rc]<= ky) x =rc;
 98             else    break;
 99         }
100         if(x && key[x] <= ky)   splay(x,0);
101         else x = -1;
102         return x;
103     }
104  
105  
106     void del(int x,int ky,int f)
107     {
108         if(!x) return ;
109         if(key[x] > ky)
110             del(lc,ky,x);
111         else
112         {
113             cnt += sz[lc] + 1;
114             ch[f][ch[f][1]==x] = rc , fa[rc] = f;
115             if(!f) root = rc;
116             del(rc, ky, f);
117         }
118         push_up(x);
119     }
120  
121     int kth( int k)
122     {
123         int x = root;
124         if(sz[x] < k) return -1;
125         while(x)
126         {
127             push_down(x);
128             if(k == sz[lc] + 1) break;
129             if(k > sz[lc])
130                 k -= sz[lc] + 1, x = rc;
131             else
132                 x = lc;
133         }
134         if(x)   splay(x,0);
135         else x = -1;
136         return x;
137     }
138  
139     int pred( void)
140     {
141         int x = root;
142         if(!x || !lc)   return -1;
143         while(lc)    push_down(x), x = lc;
144         splay( x, 0);
145         return x;
146     }
147  
148     int succ( void)
149     {
150         int x = root;
151         if(!x || !rc) return -1;
152         while(rc)   push_down(x), x = rc;
153         splay( x, 0);
154         return x;
155     }
156  
157     void debug( int x )
158     {
159         if( !x ) return;
160         if(lc) debug( lc );
161         printf("%d ", key[x] );
162         if(rc) debug( rc );
163     }
164  
165 } sp;
166  
167 int main(void)
168 {
169     //freopen("in.acm","r",stdin);
170     int n,m,x,y,d=0,tot=0;
171     char op[5];
172     scanf("%d%d",&n,&m);
173     sp.init();
174     while(n--)
175     {
176         scanf("%s%d",op,&x);
177         if(op[0]=='I')
178         {
179             if(x>=m) sp.insert(x-d,0);
180         }
181         else if(op[0]=='A')
182             d+=x;
183         else if(op[0]=='S')
184             d-=x,sp.del(sp.root,m-d-1,0);
185         else
186         {
187             x = sp.sz[sp.root] - x + 1;
188             if( x <= 0)  {printf("-1\n");continue;}
189             y = sp.kth(x);
190             printf("%d\n",sp.key[y]+d);
191         }
192     }
193     printf("%d\n",sp.cnt);
194     return 0;
195 }

 

 
posted @ 2017-10-13 15:50  weeping  阅读(199)  评论(0编辑  收藏  举报