首页 > 代码库 > bzoj1503: [NOI2004]郁闷的出纳员 fhqtreap版
bzoj1503: [NOI2004]郁闷的出纳员 fhqtreap版
这道题写法和之前差不多 但是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; }
bzoj1503: [NOI2004]郁闷的出纳员 fhqtreap版
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。