1. 程式人生 > >bzoj1503 郁悶的出納員

bzoj1503 郁悶的出納員

公司 inpu tdi 專業 不知道 += output roo 開公司

Description

OIER公司是一家大型專業化軟件公司,有著數以萬計的員工。作為一名出納員,我的任務之一便是統計每位員工的 工資。這本來是一份不錯的工作,但是令人郁悶的是,我們的老板反復無常,經常調整員工的工資。如果他心情好 ,就可能把每位員工的工資加上一個相同的量。反之,如果心情不好,就可能把他們的工資扣除一個相同的量。我 真不知道除了調工資他還做什麽其它事情。工資的頻繁調整很讓員工反感,尤其是集體扣除工資的時候,一旦某位 員工發現自己的工資已經低於了合同規定的工資下界,他就會立刻氣憤地離開公司,並且再也不會回來了。每位員 工的工資下界都是統一規定的。每當一個人離開公司,我就要從電腦中把他的工資檔案刪去,同樣,每當公司招聘 了一位新員工,我就得為他新建一個工資檔案。老板經常到我這邊來詢問工資情況,他並不問具體某位員工的工資 情況,而是問現在工資第k多的員工拿多少工資。每當這時,我就不得不對數萬個員工進行一次漫長的排序,然後 告訴他答案。好了,現在你已經對我的工作了解不少了。正如你猜的那樣,我想請你編一個工資統計程序。怎麽樣 ,不是很困難吧?

Input

第一行有兩個非負整數n和min。n表示下面有多少條命令,min表示工資下界。 接下來的n行,每行表示一條命令。命令可以是以下四種之一: 名稱 格式 作用 I命令 I_k 新建一個工資檔案,初始工資為k。 如果某員工的初始工資低於工資下界,他將立刻離開公司。 A命令 A_k 把每位員工的工資加上k S命令 S_k 把每位員工的工資扣除k F命令 F_k 查詢第k多的工資 _(下劃線)表示一個空格,I命令、A命令、S命令中的k是一個非負整數,F命令中的k是一個正整數。 在初始時,可以認為公司裏一個員工也沒有。 I命令的條數不超過100000 A命令和S命令的總條數不超過100 F命令的條數不超過100000 每次工資調整的調整量不超過1000 新員工的工資不超過100000

Output

輸出行數為F命令的條數加一。 對於每條F命令,你的程序要輸出一行,僅包含一個整數,為當前工資第k多的員工所拿的工資數, 如果k大於目前員工的數目,則輸出-1。 輸出文件的最後一行包含一個整數,為離開公司的員工的總數。

Sample Input

9 10
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2

Sample Output

10
20
-1
2
直接用Treap來維護第K大公司。 每來一個員工如果給的工資大於期望,那麽就扔進Treap裏面。 加工資直接循環,減工資時,如果當期那點小於期望,就刪了。 註意幾個細節:
刪點重復的直接一起刪。 一定要先刪點,然後再減工資,要不然刪一半時二叉搜索樹性質無法保證。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <queue>
#define in(a) a=read()
#define MAXN 200010
#define REP(i,k,n)  for(int i=k;i<=n;i++)
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch==-)
            f=-1;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-0;
    return x*f;
}
struct node{
    int data,l,r,key,c,size;
}tree[MAXN];
int n,m,total,root,fair[MAXN],ans;
int dis=0;
inline void update(int i){
    tree[i].size=tree[tree[i].l].size+tree[tree[i].r].size+tree[i].c;
    return ;
}
inline int ran(){
    int t=rand();
    return (t*68901935LL)%2147483647;
}
inline void zag(int &i){
    int t=tree[i].r;
    tree[i].r=tree[t].l;
    tree[t].l=i;
    tree[t].size=tree[i].size;
    update(i);
    i=t;
    return ;
}
inline void zig(int &i){
    int t=tree[i].l;
    tree[i].l=tree[t].r;
    tree[t].r=i;
    tree[t].size=tree[i].size;
    update(i);
    i=t;
    return ;
}
inline void insert(int &i,int k){
    if(!i){
        i=++total;
        tree[i].data=k;
        tree[i].key=ran();
        tree[i].c=tree[i].size=1;
        return ;
    }
    tree[i].size++;
    if(tree[i].data==k)  tree[i].c++;
    else if(k<tree[i].data){
        insert(tree[i].l,k);
        if(tree[tree[i].l].key<tree[i].key)  zig(i);
    }
    else{
        insert(tree[i].r,k);
        if(tree[tree[i].r].key<tree[i].key)  zag(i);
    }
    return ;
}
inline void delate(int &i,int k){
    if(!i)  return ;
    if(i==k){
        if(!tree[i].l || !tree[i].r)  i=tree[i].l+tree[i].r;
        else  if(tree[tree[i].l].key<tree[tree[i].r].key)  zig(i),delate(i,k);
        else  zag(i),delate(i,k);
    }
    else  if(tree[k].data<tree[i].data)  tree[i].size-=tree[k].c,delate(tree[i].l,k);
    else  tree[i].size-=tree[k].c,delate(tree[i].r,k);
    return ;
}
inline int getnum(int i,int k){
    if(!i)  return -1;
    if(tree[tree[i].r].size>=k) return getnum(tree[i].r,k);
    k-=tree[tree[i].r].size;
    if(tree[i].c>=k){
        return tree[i].data;
    }
    k-=tree[i].c;
    return getnum(tree[i].l,k);
}
int main(){
    in(n);in(m);
    char c;
    int a;
    REP(Stan,1,n){
        cin>>c;in(a);
        if(c==I){
            if(a<m)  continue;
            insert(root,a);
        }
        if(c==A)
            REP(i,1,total)  if(!fair[i])  tree[i].data+=a;
        if(c==S){
            REP(i,1,total){
                if(fair[i]) continue;
                if(tree[i].data-a<m){
                      ans+=tree[i].c,delate(root,i),fair[i]=1;
                }
            }
            REP(i,1,total)
                if(!fair[i])  tree[i].data-=a;
        }
        if(c==F){printf("%d\n",getnum(root,a));}
    }
    cout<<ans<<endl;
    return 0;
}
    

bzoj1503 郁悶的出納員