P1486 [NOI2004] 郁闷的出纳员 FHQ-Treap

Posted 昵称很长很长真是太好了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1486 [NOI2004] 郁闷的出纳员 FHQ-Treap相关的知识,希望对你有一定的参考价值。

题意:

第一行有两个整数 n n n m i n ⁡ min⁡ min n n n 表示下面有多少条命令, m i n ⁡ min⁡ min 表示工资下界。

接下来的 n n n 行,每行一个字符 x x x和一个整数 k k k,表示一条命令。命令可以是以下四种之一:

I k 新建一个工资档案,初始工资为 k。如果某员工的初始工资低于工资下界,他将立刻离开公司。

A k 把每位员工的工资加上 k 。

S k 把每位员工的工资扣除 k。

F k 查询第 k 多的工资。

在初始时,可以认为公司里一个员工也没有。

题解:
只做过一两道平衡树的题目,不过有一说一,这道题感觉非常模板。
其实就是模板题加了一个操作,区间修改的操作。
打一个lazy即可。
fhq-treap非常容易实现。

代码:

#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
using namespace std;

const int maxn=3e5+10;

mt19937 rnd(233);

int imin;

struct FHQ{
    int cnt,root;
    int ls[maxn],rs[maxn],val[maxn],key[maxn],siz[maxn];
    int lazy[maxn];

    int newnode(int x){
        val[++cnt]=x;
        key[cnt]=rnd();
        siz[cnt]=1;
        return cnt;
    }
    void update(int node){
        siz[node]=siz[ls[node]]+siz[rs[node]]+1;
    }

    void push_down(int node){
        if(ls[node]){
            lazy[ls[node]]+=lazy[node];
            val[ls[node]]+=lazy[node];
        }
        if(rs[node]){
            lazy[rs[node]]+=lazy[node];
            val[rs[node]]+=lazy[node];
        }
        lazy[node]=0;
    }
    void spilt_val(int node,int vals,int &x,int &y){
        if(!node){
            x=y=0;
            return ;
        }
        if(lazy[node]) push_down(node);
        if(val[node]<=vals){
            x=node;
            spilt_val(rs[node],vals,rs[node],y);
        }
        else{
            y=node;
            spilt_val(ls[node],vals,x,ls[node]);
        }
        update(node);
    }
    int mer(int x,int y){
        if(!x||!y) return x+y;
        if(key[x]>key[y]){
            rs[x]=mer(rs[x],y);
            update(x);
            return x;
        }
        else{
            ls[y]=mer(x,ls[y]);
            update(y);
            return y;
        }
    }
    int x,y,z;
    void insert(int vals){
        if(vals<imin) return;
        spilt_val(root,vals,x,y);
        root=mer(mer(x,newnode(vals)),y);
    }
    void add(int x){
        val[root]+=x;
        lazy[root]+=x;
    }
    void sub(int x){
        val[root]-=x;
        lazy[root]-=x;
        spilt_val(root,imin-1,x,y);
        root=y;
    }
    int get_kth(int rank){
        if(siz[root]<rank) return -1;
        rank=siz[root]-rank+1;
        int node=root;
        while(node){
            push_down(node);
            if(siz[ls[node]]+1==rank) break;
            else if(siz[ls[node]]>=rank) node=ls[node];
            else{
                rank-=siz[ls[node]]+1;
                node=rs[node];
            }

        }
        return val[node];
    }
}tree;

signed main(){
     ios::sync_with_stdio(false);
     cin.tie(0);
    int n;
    cin>>n>>imin;
    for(int i=1;i<=n;i++){
        char c;
        int x;
        cin>>c>>x;
        if(c=='I')  tree.insert(x);
        else if(c=='A') tree.add(x);
        else if(c=='S') tree.sub(x);
        else if(c=='F'){
            int ans=tree.get_kth(x);
            //cout<<"debug  "<<tree.siz[tree.root]<<endl;
            cout<<ans<<endl;
        }
    }
    cout<<tree.cnt-tree.siz[tree.root]<<endl;

}

以上是关于P1486 [NOI2004] 郁闷的出纳员 FHQ-Treap的主要内容,如果未能解决你的问题,请参考以下文章

NOI2004郁闷的出纳员

BZOJ 1503: [NOI2004]郁闷的出纳员

BZOJ 1503: [NOI2004]郁闷的出纳员

bzoj 1503: [NOI2004]郁闷的出纳员

bzoj1503: [NOI2004]郁闷的出纳员

bzoj 1503: [NOI2004]郁闷的出纳员 平衡树