#include<iostream>
#include<cstring>
#include<cstdio>
#define inf 1000000000
using namespace std;
const int maxn=200005;
struct SplayTree
{
int son[maxn][2],pre[maxn],val[maxn];
int sum[maxn];
int rt,sz;
void pushUp(int x) {
sum[x]=sum[son[x][0]]+sum[son[x][1]]+1;
}
void newNode(int f,int& x,int a) {
x=++sz;
pre[x]=f;
val[x]=a;
sum[x]=1;
son[x][0]=son[x][1]=0;
}
void init() {
sz=rt=0;
}
void Rotate(int x,int c) {
int y=pre[x];
son[y][!c]=son[x][c];
pre[son[x][c]]=y;
pre[x]=pre[y];
if(pre[x])
son[pre[y]][son[pre[y]][1]==y]=x;
son[x][c]=y;
pre[y]=x;
pushUp(y);
}
void Splay(int x,int goal) {
while(pre[x]!=goal) {
if(pre[pre[x]]==goal) {
if(son[pre[x]][0]==x)
Rotate(x,1);
else
Rotate(x,0);
}
else {
int y=pre[x],z=pre[y];
if(son[z][0]==y) {
if(son[y][0]==x) {
Rotate(y,1);
Rotate(x,1);
}
else {
Rotate(x,0);
Rotate(x,1);
}
}
else {
if(son[y][1]==x) {
Rotate(y,0);
Rotate(x,0);
}
else {
Rotate(x,1);
Rotate(x,0);
}
}
}
}
pushUp(x);
if(goal==0)
rt=x;
}
void Insert(int a) {
if(rt==0) {
rt=++sz;
val[rt]=a;
sum[rt]=1;
son[rt][0]=son[rt][1]=0;
return;
}
int x=rt;
while(son[x][val[x]<a])
x=son[x][val[x]<a];
newNode(x,son[x][val[x]<a],a);
Splay(sz,0);
}
int getMin(int a) { //找到大于等于a的最小值
int x=rt,Min=inf;
while(x) {
if(val[x]==a)
return a;
if(val[x]>a)
Min=min(Min,val[x]);
if(val[x]>a)
x=son[x][0];
else
x=son[x][1];
}
return Min;
}
int Find(int a) { //找到a的位置
int x=rt;
while(x) {
if(val[x]==a)
return x;
if(val[x]>a)
x=son[x][0];
else
x=son[x][1];
}
return 0;
}
int delSubTree(int &rt,int f,int x){ //删除比x小的节点
if(!rt)
return 0;
int res=0;
if(val[rt]<x){
res=sum[son[rt][0]]+1+delSubTree(son[rt][1],rt,x);
sum[son[rt][1]]=sum[rt]-res;
rt=son[rt][1];
pre[rt]=f;
}else{
res=delSubTree(son[rt][0],rt,x);
sum[rt]-=res;
}
return res;
}
int select(int a) { //找第a大的值
int x=rt;
while(true) {
if(sum[son[x][1]]==a-1) {
break;
}
if(sum[son[x][1]]>=a) {
x=son[x][1];
}
else {
a-=(sum[son[x][1]]+1);
x=son[x][0];
}
}
Splay(x,0);
return val[x];
}
}spt;
int ans;
int main()
{
spt.init();
int n,Min;
int w=0;
char op[10];
scanf("%d%d",&n,&Min);
int a;
ans=0;
while(n--) {
scanf("%s%d",op,&a);
if(op[0]=='I') {
a-=w;
if(a>=Min-w) {
spt.Insert(a);
}
}
else if(op[0]=='A') {
w+=a;
}
else if(op[0]=='S') {
w-=a;
ans+=spt.delSubTree(spt.rt,0,Min-w);
}
else {
if(a>spt.sum[spt.rt])
puts("-1");
else {
printf("%d\n",spt.select(a)+w);
}
}
}
cout<<ans<<endl;
return 0;
}
codevs 1286 郁闷的出纳员 splayTree模板
最新推荐文章于 2019-03-06 19:15:00 发布