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
Key To Problem
treap和splay都可以搞
Code
//treap
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define N
using namespace std;
struct node
{
int l,r,v,size,rnd,w;
};
node a[N];
int n,size,root,ans,min_s,delet,sum;
char s[];
void updata(int k)
{
a[k].size=a[a[k].l].size+a[a[k].r].size+;
}
void lturn(int &k)
{
int t=a[k].r;
a[k].r=a[t].l,a[t].l=k;
a[t].size=a[k].size,updata(k),k=t;
}
void rturn(int &k)
{
int t=a[k].l;
a[k].l=a[t].r,a[t].r=k;
a[t].size=a[k].size,updata(k),k=t;
}
void insert(int &k,int x)
{
if(k==)
{
k=++size;
a[k].v=x,a[k].size=a[k].w=,a[k].rnd=rand();
return ;
}
a[k].size++;
if(x>a[k].v)
{
insert(a[k].r,x);
if(a[a[k].r].rnd<a[k].rnd)lturn(k);
}else
{
insert(a[k].l,x);
if(a[a[k].l].rnd<a[k].rnd)rturn(k);
}
}
int del(int &k,int x)
{
int t=;
if(k==)return ;
if(x>a[k].v)
{
t=a[a[k].l].size+;
k=a[k].r;
return t+del(k,x);
}else
{
t=del(a[k].l,x);
a[k].size-=t;
return t;
}
}
int query(int k,int x)
{
if(k==)return ;
if(a[a[k].l].size+==x)return a[k].v+delet;
if(x<a[a[k].l].size+)return query(a[k].l,x);
else return query(a[k].r,x-a[a[k].l].size-);
}
int main()
{
// freopen("cashier.in","r",stdin);
// freopen("cashier.out","w",stdout);
cin>>n>>min_s;
while(n--)
{
int x;
scanf("%s%d",s+,&x);
if(s[]=='I'&&x>=min_s)insert(root,x-delet);
else if(s[]=='A')delet+=x;
else if(s[]=='S')
{
delet-=x;
sum+=del(root,min_s-delet);
}
else if(s[]=='F')
{
if(x>a[root].size)puts("-1");
else printf("%d\n",query(root,a[root].size-x+));
}
}
printf("%d\n",sum);
return ;
}
//splay
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100010
#define ls(x) tr[x].l
#define rs(x) tr[x].r
#define fa(x) tr[x].fa
using namespace std;
struct node
{
int l,r,fa,size,v;
};
node tr[N];
int n,m,tot,root,delta,sum;
void PushUp(int x)
{
tr[x].size=tr[ls(x)].size+tr[rs(x)].size+;
}
void zig(int x)
{
int y=fa(x);
int z=fa(y);
if(y==ls(z))ls(z)=x;
else rs(z)=x;
fa(x)=z,ls(y)=rs(x),fa(y)=x,fa(rs(x))=y,rs(x)=y;
PushUp(y),PushUp(x);
if(y==root)root=x;
}
void zag(int x)
{
int y=fa(x);
int z=fa(y);
if(y==ls(z))ls(z)=x;
else rs(z)=x;
fa(x)=z,rs(y)=ls(x),fa(y)=x,fa(ls(x))=y,ls(x)=y;
PushUp(y),PushUp(x);
if(y==root)root=x;
}
void Splay(int x,int d)
{
while(fa(x)!=d)
{
if(ls(fa(x))==x)zig(x);
else zag(x);
}
}
void insert(int x)
{
if(!root)
{
root=++tot;
tr[tot].v=x,tr[tot].size=;
return ;
}
int p=root,z;
while(p)
{
z=p;
tr[p].size++;
if(x<tr[p].v)p=ls(p);
else p=rs(p);
}
if(x<tr[z].v)ls(z)=++tot;
else rs(z)=++tot;
tr[tot].v=x,tr[tot].size=,fa(tot)=z;
Splay(tot,);
}
int del(int &x,int f)
{
if(!x)return ;
int k;
if(tr[x].v+delta<m)
{
k=del(rs(x),x)+tr[ls(x)].size+;
tr[rs(x)].size=tr[x].size-k;
x=rs(x),fa(x)=f;
}else
{
k=del(ls(x),x);
tr[x].size-=k;
}
return k;
}
int query(int x,int k)
{
if(k<=tr[rs(x)].size)return query(rs(x),k);
if(k==tr[rs(x)].size+)return tr[x].v;
return query(ls(x),k-tr[rs(x)].size-);
}
int main()
{
cin>>n>>m;
for(int i=;i<=n;i++)
{
char s[];
int x;
scanf("%s%d",s,&x);
if(s[]=='I'&&x>=m)insert(x-delta);
else if(s[]=='A')delta+=x;
else if(s[]=='S')delta-=x,sum+=del(root,);
else if(s[]=='F'&&x>tr[root].size)puts("-1");
else if(s[]=='F')printf("%d\n",query(root,x)+delta);
}
cout<<sum<<endl;
return ;
}