1. 程式人生 > >bzoj1503: [NOI2004]郁悶的出納員 fhqtreap版

bzoj1503: [NOI2004]郁悶的出納員 fhqtreap版

opened truct names pre splay blog etc int find

這道題寫法和之前差不多 但是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

bzoj1503: [NOI2004]郁悶的出納員 fhqtreap版