1. 程式人生 > >「NOI2004」「LuoguP1486」郁悶的出納員

「NOI2004」「LuoguP1486」郁悶的出納員

他還 algorithm n) 有著 www. 行數 每次 心情不好 學會

Descrption

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

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

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

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

如果某個員工的初始工資低於最低工資標準,那麽將不計入最後的答案內

Input&&Output

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是一個正整數。

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

Output

輸出文件的行數為F命令的條數加一。

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

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

Sample

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

題解

還是用新學會的vector亂搞。「模板」普通平衡樹(題解那裏講了構造方法

有一個小優化:利用差分思想記錄一個x,初始為0 漲工資就x+=k而不是遍歷每個點

在降工資的時候再算(然而這道題A和S不超過100 咕嘰嘰

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<vector>
 5 using namespace std;
 6 vector<int>a;
 7 int main()
 8 {
 9     //freopen("a.in","r",stdin);
10     int n,min;
11     cin>>n>>min;
12     int x=0;
13     int ans=0;
14     for(int i=1;i<=n;++i)
15     {
16         char ch;
17         int k;
18         cin>>ch>>k;
19         switch(ch)
20         {
21             case(I):if(k>=min)a.insert(upper_bound(a.begin(),a.end(),k-x),k-x);break;
22             case(A):x+=k;break;
23             case(S):x-=k;while(a[0]+x<min&&a.size()){a.erase(a.begin());ans++;}break;
24             case(F):if(a.size()<k)cout<<-1<<endl;else cout<<a[a.size()-k]+x<<endl;break;
25         }
26     }
27     cout<<ans;
28     return 0;
29 }

最優解都排倒數了QAQ但是真好碼

「NOI2004」「LuoguP1486」郁悶的出納員