noi2004-鬱悶的出納員(cashier) 解題報告

  NOI2004鬱悶的出納員

【問題描述】

OIER公司是一家大型專業化軟件公司,有着數以萬計的員工。作爲一名出納員,我的任務之一便是統計每位員工的工資。這本來是一份不錯的工作,但是令人鬱悶的是,我們的老闆反覆無常,經常調整員工的工資。如果他心情好,就可能把每位員工的工資加上一個相同的量。反之,如果心情不好,就可能把他們的工資扣除一個相同的量。我真不知道除了調工資他還做什麼其它事情。

工資的頻繁調整很讓員工反感,尤其是集體扣除工資的時候,一旦某位員工發現自己的工資已經低於了合同規定的工資下界,他就會立刻氣憤地離開公司,並且再也不會回來了。每位員工的工資下界都是統一規定的。每當一個人離開公司,我就要從電腦中把他的工資檔案刪去,同樣,每當公司招聘了一位新員工,我就得爲他新建一個工資檔案。

老闆經常到我這邊來詢問工資情況,他並不問具體某位員工的工資情況,而是問現在工資第k多的員工拿多少工資。每當這時,我就不得不對數萬個員工進行一次漫長的排序,然後告訴他答案。

好了,現在你已經對我的工作了解不少了。正如你猜的那樣,我想請你編一個工資統計程序。怎麼樣,不是很困難吧?

【輸入文件】

cashier.in第一行有兩個非負整數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是一個正整數。

在初始時,可以認爲公司裏一個員工也沒有。

【輸出文件】

輸出文件cashier.out的行數爲F命令的條數加一。

對於每條F命令,你的程序要輸出一行,僅包含一個整數,爲當前工資第k多的員工所拿的工資數,如果k大於目前員工的數目,則輸出-1。

輸出文件的最後一行包含一個整數,爲離開公司的員工的總數。

【樣例輸入】

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

【樣例輸出】

10 
20 
-1 
2 

【約定】

I命令的條數不超過100000

A命令和S命令的總條數不超過100

F命令的條數不超過100000

每次工資調整的調整量不超過1000

新員工的工資不超過100000

 

分析:由於插入命令、詢問命令最多有100000個,所以都必須在均攤時間複雜度爲O(logn)的時限內實現插入、詢問、刪除等操作,故想到使用平衡二叉樹。由於要支持找第k大元素這一個操作,可以用跳躍表或者是sbt,我用的是sbt。這裏有個小技巧:對於A命令和S命令,不用對每個元素的值進行修改,只需要記錄下累計變化量爲多少,再刪除判斷和插入時做處理就行了。插入時,節點的權值應變爲x-delta,刪除時變爲x+delta。

 

PS:sbt理解得不夠透徹啊..關鍵上寫法太nb,一時間無法運用自如,經常寫漏關鍵語句...注意程序中attention的地方。

 

代碼:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章