题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1503
思路:把每次减工资或加工资都用一个变量add记下,加入一个员工时,给的初始工资是,因为树中的所有人都是默认工资加上 add,把他加入树中时应该设工资为x-add。删减时应该删减树中工资少于lim-add的。
splay模板题:
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
struct node
{
int v,f,ch[2],sum[2];
} T[100010];
int n,limit,x,add,root,tot,del;
char ch[5];
int new_node(int &root,int far,int k)
{
root=++tot;
T[root].ch[0]=T[root].ch[1]=0;
T[root].sum[0]=T[root].sum[1]=0;
T[root].f=far;
T[root].v=k;
return tot;
}
void rol(int r,int kind)//旋转
{
int far=T[r].f,gar=T[far].f;
T[far].ch[!kind]=T[r].ch[kind];
T[T[r].ch[kind]].f=far;
T[r].ch[kind]=far;
T[far].f=r;
T[gar].ch[T[gar].ch[1]==far]=r;
T[r].f=gar;
T[far].sum[!kind]=T[r].sum[kind];
T[r].sum[kind]+=(T[far].sum[kind]+1);
return ;
}
void splay(int r,int goal)//把r转到根节点
{
while(T[r].f!=goal)
{
int far=T[r].f,gar=T[far].f;
int kind=T[gar].ch[0]==far;
if(gar==goal) rol(r,T[far].ch[0]==r);
else
{
if(T[far].ch[kind]==r)
{
rol(r,!kind);
rol(r,kind);
}
else
{
rol(far,kind);
rol(r,kind);
}
}
}
root=r;
return ;
}
int Insert(int k)//插入数据
{
int r=root;
while(T[r].ch[T[r].v<k])r=T[r].ch[T[r].v<k];
new_node(T[r].ch[T[r].v<k],r,k);
splay(T[r].ch[T[r].v<k],0);
return 1;
}
int Find(int r,int lim)//找到最左边的与其相同的节点找不到返回-1
{
while(r)
{
if(T[r].v==lim)
{
int p=Find(T[r].ch[0],lim);
if(p==-1) return r;
return p;
}
if(T[r].v>lim)
{
r=T[r].ch[0];
}
else
r=T[r].ch[1];
}
return -1;
}
void Delete(int r,int lim)//删除节点
{
int de=Find(r,lim-add);//如果有相同的,找到最左边的与它相同的
if(de==-1)//如果没有相同的,加入一个节点与器相同,删除它左边的树,包括它
{
Insert(lim-add);
del+=T[root].sum[0];
int re=T[root].ch[1];
T[re].f=0,root=re;
}
else//有相同的,把它变为根,删除它左边的点
{
splay(de,0);
del+=T[de].sum[0];
T[de].sum[0]=0;
T[de].ch[0]=0;
}
return ;
}
//int Query(int r,int k)//遍历整颗树
//{
// if(T[r].sum[0]+T[r].sum[1]<k) return -1;
//}
int Query(int r,int k)//查找第K大
{
if(T[r].sum[0]+T[r].sum[1]+1<k) return -1;
while(T[r].sum[1]!=k-1)
{
if(T[r].sum[1]<k-1) k-=T[r].sum[1]+1,r=T[r].ch[0];
else r=T[r].ch[1];
}
return add+T[r].v;
}
void see(int r)//debug
{
printf("%d\n",T[r].v);
if(T[r].ch[1]) see(T[r].ch[1]);
if(T[r].ch[0]) see(T[r].ch[0]);
}
int main()
{
while(~scanf("%d%d",&n,&limit))
{
add=root=del=0;
for(int i=1; i<=n; i++)
{
scanf("%s %d",ch,&x);
if(ch[0]=='I'&&x>=limit) root==0?new_node(root,0,x-add):Insert(x-add);
else if(ch[0]=='A') add+=x;
else if(ch[0]=='S') add-=x,Delete(root,limit);
else if(ch[0]=='F') printf("%d\n",Query(root,x));
// see(root);
}
printf("%d\n",del);
}
}