bzoj1503: [NOI2004]郁闷的出纳员
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1503
题目:
1503: [NOI2004]郁闷的出纳员
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 12285 Solved: 4389
[Submit][Status][Discuss]
Description
OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?
Input
Output
输出文件的行数为F命令的条数加一。对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。输出文件的最后一行包含一个整数,为离开公司的员工的总数。
Sample Input
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2
Sample Output
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 }
作者:weeping
出处:www.cnblogs.com/weeping/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。