1. 程式人生 > >bzoj 1503: [NOI2004]郁悶的出納員 -- 權值線段樹

bzoj 1503: [NOI2004]郁悶的出納員 -- 權值線段樹

images 自己的 為什麽 一次 output alt image fin getc

1503: [NOI2004]郁悶的出納員

Time Limit: 5 Sec Memory Limit: 64 MB

Description

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

Input

技術分享

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

HINT

I命令的條數不超過100000 A命令和S命令的總條數不超過100 F命令的條數不超過100000 每次工資調整的調整量不超過1000 新員工的工資不超過100000

Source

為什麽你萌都寫平衡樹,,只有我寫線段樹嗎。。QaQ

建權值線段樹,支持單點添加區間賦值(我比較lan,寫到了一個函數裏)

對於加減工資可以單獨儲存,新加點權值減去之前總共更改的工資,加入線段樹中即可

由於可能出現負值,我就每個數都加上了100001,查詢的時候在減去就好。。

#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include
<algorithm> using namespace std; #define ll long long #define X 100001 #define N 300001 #define M 1200010 inline int rd() { int x=0,f=1;char ch=getchar(); while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();} while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();} return x*f; } int sum[M],lz[M]; inline void pd(int p) { if(lz[p]) { lz[p<<1|1]=lz[p<<1]=1; sum[p<<1]=sum[p<<1|1]=0; lz[p]=0; } } void add(int p,int l,int r,int L,int R,int x,bool f) { if(l==L&&R==r) { if(f) sum[p]++; else{sum[p]=x;lz[p]=1;} return; } pd(p); int mid=l+r>>1; if(R<=mid) add(p<<1,l,mid,L,R,x,f); else if(L>mid) add(p<<1|1,mid+1,r,L,R,x,f); else { add(p<<1,l,mid,L,mid,x,f); add(p<<1|1,mid+1,r,mid+1,R,x,f); } sum[p]=sum[p<<1]+sum[p<<1|1]; } int fd(int p,int l,int r,int k) { if(l==r) return l; pd(p); int mid=l+r>>1; if(sum[p<<1|1]>=k) return fd(p<<1|1,mid+1,r,k); else return fd(p<<1,l,mid,k-sum[p<<1|1]); } int n,mn,ans,ji; int main() { n=rd();mn=rd()+X; int x; while(n--) { char ch=getchar(); while(ch<A||ch>Z) ch=getchar(); x=rd()+X; if(ch==I) { if(x>=mn) ans++,add(1,1,N,x-ji,x-ji,1,1); } else if(ch==A) ji+=x-X; else if(ch==S) { ji-=x-X; if(mn-ji>1) add(1,1,N,1,mn-ji-1,0,0); } else sum[1]>=x-X?printf("%d\n",fd(1,1,N,x-X)+ji-X):puts("-1"); } printf("%d\n",ans-sum[1]); return 0; }

bzoj 1503: [NOI2004]郁悶的出納員 -- 權值線段樹