您的位置:首页 > 编程语言 > Qt开发

bzoj1503: [NOI2004]郁闷的出纳员 fhqtreap版

2017-06-02 21:13 441 查看

这道题写法和之前差不多 但是fhqtreap在加点的时候为了同时维护大根堆以及二叉排序树的性质所以插入时也要注意分裂

fhqteap需要判断指针是否为空 不然就会re 这个我调了很久

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=150000;
int read(){
int ans=0,f=1,c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
return ans*f;
}
int n,m,sum,mn,leave,delta;
struct node{
node *l,*r;
int sz,v,rnd;
void init(int w){sz=1; v=w; rnd=rand();}
void up(){
sz=1;
if(l) sz+=l->sz;
if(r) sz+=r->sz;
}
void split(node*&lw,node*&rw,int w){
if(!this){lw=0; rw=0; return ;}
if(w<=v){
l->split(lw,l,w);
rw=this;
}
else{
r->split(r,rw,w);
lw=this;
}
up();
}
int find(int rank){
if(!this) return 0;
int ls=l?l->sz:0;
if(ls+1==rank) return v;
else if(ls>=rank) return l->find(rank);
else return r->find(rank-ls-1);
}

}tr[M],*rt;
node* merge(node*a,node*b){
if(!a) return b;
if(!b) return a;
if(a->rnd>b->rnd){
a->r=merge(a->r,b);
a->up();
return a;
}{
b->l=merge(a,b->l);
b->up();
return b;
}
}
int main()
{

char ch[5];
int w;
n=read(); mn=read();
while(n--){
scanf("%s",ch); w=read();
if(ch[0]=='I'&&w>=mn){
tr[++sum].init(w-delta);
node *p1,*p2;
rt->split(p1,p2,w-delta);
rt=merge(merge(p1,tr+sum),p2);
}
if(ch[0]=='A') delta+=w;
if(ch[0]=='S'){
node *p;
delta-=w; rt->split(p,rt,mn-delta);
if(p) leave+=p->sz;
}
if(ch[0]=='F'){
if(!rt||w>rt->sz) { printf("-1\n"); continue;}
printf("%d\n",rt->find(rt->sz-w+1)+delta);
}
}
printf("%d\n",leave);
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: