码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-06-02 22:00:54      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:scan   turn   const   continue   noi   alt   需要   bzoj1503   ret   

这道题写法和之前差不多 但是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版

标签:scan   turn   const   continue   noi   alt   需要   bzoj1503   ret   

原文地址:http://www.cnblogs.com/lyzuikeai/p/6935177.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!