做完这一道题以后我基本就郁闷了,BZOJ上不能用ctime一直re,删了就好了,没什么好说的裸的treap拿来练版
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
using namespace std;
int n,Min;
struct Tree{
int r,size,x,times;
Tree* ch[2];
Tree(int a=0,int b=0,Tree* ll=NULL,Tree* rr=NULL){
r=a,x=b,size=1,ch[0]=ll,ch[1]=rr,times=1;
}
void init(){
size=times;
if(ch[0]!=NULL)size+=ch[0]->size;
if(ch[1]!=NULL)size+=ch[1]->size;
}
int xmp(int xx){
if(x==xx)return -1;
return xx>x;
}
};
Tree* rt=NULL;
void Rotate(Tree* &u,int d){
Tree* v=u->ch[d^1];u->ch[d^1]=v->ch[d],v->ch[d]=u;
u->init();v->init();u=v;
}
void insert(Tree* &u,int x){
if(u==NULL){
u=new Tree(rand(),x);
}else{
int d=u->xmp(x);
if(d!=-1){
insert(u->ch[d],x);
if(u->ch[d]->r > u->r)Rotate(u,d^1);
}
else u->times++,u->size++;
}
u->init();
}
int remove(Tree* &u,int x){
int d=u->xmp(x),p;
if(d==-1){
if(u->ch[0]==NULL){
p=u->times;u=u->ch[1];
}
else if(u->ch[1]==NULL){
p=u->times;u=u->ch[0];
}
else{
if(u->ch[0]->r > u->ch[1]->r)d=1;
else d=0;
Rotate(u,d);
p=remove(u->ch[d],x);
}
}else p=remove(u->ch[d],x);
if(u!=NULL)u->init();
return p;
}
int findk(Tree* u,int x){
if(x> u->size)return -1;
int rs=0;
if(u->ch[1]!=NULL)rs=u->ch[1]->size;
if(x> rs && x<=rs+u->times)return u->x;
if(u->ch[1]!=NULL&&x<=rs)return findk(u->ch[1],x);
else return findk(u->ch[0],x- u->times -rs);
}
int find_min(){
Tree* u=rt;
while(u->ch[0]!=NULL)u=u->ch[0];
return u->x;
}
int main(){
int now=0,all=0;
scanf("%d%d",&n,&Min);
srand(n*Min%1007);
char s[5];
for(int x,i=1;i<=n;i++){
scanf("%s%d",s,&x);
if(s[0]=='I'&&x>=Min){
insert(rt,x-now);
}else if(s[0]=='A'){
now+=x;
}else if(s[0]=='S'){
now-=x;int p;
while(rt!=NULL&&(p=find_min())+now<Min)all+=remove(rt,p);
}else if(s[0]=='F'){
if(rt==NULL||x>rt->size) puts("-1");
else printf("%d\n",findk(rt,x)+now);
}
}
printf("%d",all);
return 0;
}