这道题还不如叫郁闷的楼主。
因为没看清楚题目要求的是找出第K大的数(而不是第K小数),然后SB的DEBUG了4个小时。。。。
好吧,讲讲思路。
首先是输入,当这个人的起始工资是小于最小额的时候,是不能makefile的,所以这个人数也不用统计。
关于增加工资和减少工资,我们可以开另外一个变量add来存,每次减少工资的时候,delete掉当前工资小于MIN - add的人。
这道题主要考虑的还是Splay树的基本操作,当然对于我这种弱菜才需要DEBUG这么久。。。
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> #include <cstring> #include <queue> #include <set> #include <vector> #include <stack> #include <map> #include <iomanip> #define PI acos(-1.0) #define Max 2505 #define inf 1<<28 #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define REP(i,s,t) for(int i=(s);i<=(t);++i) #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define mp(a,b) make_pair(a,b) #define PII pair<int,int> using namespace std; int root , tot ; int fa[1111111] , ch[1111111][2] ,data[1111111] , num[1111111] ; int n , m ; void push_up(int x) { num[x] = num[ch[x][0]] + num[ch[x][1]] + 1 ; } void rotate(int x ,int kind) { int y = fa[x] ; ch[y][!kind] = ch[x][kind] ; fa[ch[x][kind]] = y ; if(fa[y])ch[fa[y]][ch[fa[y]][1] == y] = x ; fa[x] = fa[y] ; ch[x][kind] = y ; fa[y] = x ; push_up(y) ; push_up(x) ; } void Splay(int x ,int s ) { //将节点x转到节点s下面 //push_down(x) ; while(fa[x] != s) { if(fa[fa[x]] == s)rotate(x ,ch[fa[x]][0] == x) ; else { int y = fa[x] ; int z = fa[y] ; int kind = ( ch[z][0] == y ); if(ch[y][kind] == x) { rotate(x ,!kind ) ; rotate(x , kind ) ; } else { rotate(y , kind ) ; rotate(x , kind ) ; } } } push_up(x) ; if(s == 0)root = x ; } void insert(int x) { if(!root) { root = ++ tot ; data[root] = x ; fa[root] = 0 ; ch[root][0] = ch[root][1] = 0 ; num[root] = 1 ; return ; } int xx = root ; int yy ; while(xx) { yy = xx ; num[xx] ++ ; if(x < data[xx]) { xx = ch[xx][0] ; } else { xx = ch[xx][1] ; } } if(x < data[yy]) { ch[yy][0] = ++ tot ; } else { ch[yy][1] = ++ tot ; } fa[tot] = yy ; data[tot] = x ; num[tot] = 1 ; Splay(tot ,0) ; return ; } int ans = 0 ; void Delete(int k) { int x = root ; int xx = 0 ; while(x) { if(data[x] < k) { xx = x ; x = ch[x][1] ; } else { x = ch[x][0] ; } } if(!xx)return ; Splay(xx , 0) ; if(ch[xx][1] == 0) { root = 0 ; return ; } root = ch[xx][1] ; fa[root] = 0 ; } int addd = 0 ; void get_K(int k ) { if(k < 1) { printf("-1\n") ; return ; } int x = root ; while(ch[x][0] || ch[x][1]) { if(k == num[ch[x][0]] + 1)break ; else if(k < num[ch[x][0]] + 1) { x = ch[x][0] ; } else { k -= num[ch[x][0]] + 1 ; x = ch[x][1] ; } } printf("%d\n",data[x] + addd) ; return ; } void Treaval(int x) { if(x) { Treaval(ch[x][0]); printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d \n",x,ch[x][0],ch[x][1],fa[x],num[x],data[x] + addd); Treaval(ch[x][1]); } } int main() { #ifndef ONLINE_JUDGE freopen("D:\\acm.txt","r",stdin) ; #endif scanf("%d%d",&n,&m) ; ans = 0 ; addd = 0 ; char op ; tot = root = 0 ; int first = 0 ; int cc = n ; int xx ; int people = 0 ; REP(i , 0 , n - 1) { scanf("\n") ; scanf("%c %d",&op,&xx) ; if(op == 'I' && xx >= m) { //build a new file insert(xx - addd) ; people ++ ; first = 1 ; } else if(op == 'A') { //add the money addd += xx ; } else if(op == 'S') { //decrease the money addd -= xx ; Delete(m - addd) ; } else if(op == 'F') { //print the kth money get_K(num[root] - xx + 1) ; } } printf("%d\n",people - num[root]) ; return 0 ; }