• P1486 [NOI2004]郁闷的出纳员


    思路

    平衡树的题目
    题目中的全部减少可以通过维护全局的减少量S(不过我使用了打tag的方式),然后每次插入的时候插入(v_i-S),删除的时候直接在平衡树上二分移除对应的子树即可

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    int Nodecnt=0,root,n,lim;
    struct Node{
        int lson,rson,sz,val,ran,add,times;
    }Treap[100100*2];
    queue<int> q;
    void throwin(int x){
        q.push(x);
    }
    int getnew(int val){
        int o;
        if(q.size())
            o=q.front(),q.pop();
        else
            o=++Nodecnt;
        Treap[o].lson=Treap[o].rson=0;
        Treap[o].sz=Treap[o].times=1;
        Treap[o].ran=rand();
        Treap[o].val=val;
        Treap[o].add=0;
        return o;
    }
    void pushup(int o){
        Treap[o].sz=Treap[Treap[o].lson].sz+Treap[Treap[o].rson].sz+Treap[o].times;
    }
    void pushdown(int o){
        if(Treap[o].add){
            Treap[Treap[o].lson].val+=Treap[o].add;
            Treap[Treap[o].rson].val+=Treap[o].add;
            Treap[Treap[o].lson].add+=Treap[o].add;
            Treap[Treap[o].rson].add+=Treap[o].add;
            Treap[o].add=0;
        }
    }
    void rorateL(int &o){
        int x=Treap[o].rson;
        pushdown(o);
        pushdown(x);
        Treap[o].rson=Treap[x].lson;
        Treap[x].lson=o;
        pushup(o);
        pushup(x);
        o=x;
    }
    void rorateR(int &o){
        int x=Treap[o].lson;
        pushdown(o);
        pushdown(x);
        Treap[o].lson=Treap[x].rson;
        Treap[x].rson=o;
        pushup(o);
        pushup(x);
        o=x;
    }
    void insert(int val,int &o){
        if(!o){
            o=getnew(val);
            return;
        }
        pushdown(o);
        Treap[o].sz++;
        if(val<Treap[o].val){
            insert(val,Treap[o].lson);
            if(Treap[Treap[o].lson].ran<Treap[o].ran)
                rorateR(o);
        }
        else if(val>Treap[o].val){
            insert(val,Treap[o].rson);
            if(Treap[Treap[o].rson].ran<Treap[o].ran)
                rorateL(o);
        }
        else{
            Treap[o].times++;
        }
    }
    void del(int val,int &o){
        if(o==0)
            return;
        pushdown(o);
        if(Treap[o].val==val){
            Treap[o].lson=0;
            pushup(o);
            return;
        }
        else if(Treap[o].val<val&&Treap[o].rson){
            rorateL(o);
            del(val,o);
            pushup(o);
            return;
        }
        else if(Treap[o].val<val){
            o=0;
            return;
        }
        else if(Treap[o].val>val){
            del(val,Treap[o].lson);
            pushup(o);
            return;
        }
    }
    int query(int val,int o){
        if(!o)
            return -1;
        pushdown(o);
        if(val>=Treap[Treap[o].rson].sz+1&&val<=Treap[Treap[o].rson].sz+Treap[o].times)
            return Treap[o].val;
        else if(val>Treap[Treap[o].rson].sz+Treap[o].times)
            return query(val-Treap[Treap[o].rson].sz-Treap[o].times,Treap[o].lson);
        else
            return query(val,Treap[o].rson);
    }
    int main(){
        int cnt=0;
        scanf("%d %d",&n,&lim);
        for(int i=1;i<=n;i++){
            char c=getchar();
            while(c!='I'&&c!='A'&&c!='S'&&c!='F')
                c=getchar();
            if(c=='I'){
                int k;
                scanf("%d",&k);
                if(k<lim){
                    // cnt++;
                    continue;
                }
                insert(k,root);
            }
            else if(c=='A'){
                int k;
                scanf("%d",&k);
                Treap[root].val+=k;
                Treap[root].add+=k;
                pushdown(root);
            }
            else if(c=='S'){
                int k,t;
                scanf("%d",&k);
                Treap[root].val-=k;
                Treap[root].add-=k;
                pushdown(root);
                int tmp=Treap[root].sz;
                del(lim,root);
                cnt+=tmp-Treap[root].sz;
            }
            else{
                int k;
                scanf("%d",&k);
                printf("%d
    ",query(k,root));
            }
        }
        printf("%d
    ",cnt);
        return 0;
    }
    
  • 相关阅读:
    原创 ios绘制 圆形气泡
    ios 线程安全单例写法
    (转)ios中点击地图控件MKMapView的某点获取该点的经纬度
    使用正则提取url(iOS)
    MAC系统崩溃,使用命令行复制硬盘内容
    UISearchBar控件UI操作
    app发布流程详解
    App Store审核指南(中文版)2010版
    GCD详解
    iOS扫描二维码(系统方法)
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10903367.html
Copyright © 2020-2023  润新知