NOI2004, 洛谷P1486 鬱悶的出納員

2021-08-22 10:05:24 字數 3128 閱讀 8024

題目描述

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

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

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

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

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

輸入輸出格式

輸入格式:

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

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

輸出格式:

輸出檔案的行數為f命令的條數加一。

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

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

這道題調了很久, 就是不知道**錯了, 在翻看題解的時候, 有人說開始初始工資低於最低工資的直接開除, 不計入答案…修改後就過了.

這一方面是題目沒說清楚, 我真的沒找到這句話. 另一方面也是我的問題, 在我開始的模型裡只有執行s操作時才會刪除節點, 不在插入時直接刪除的話, 樹上的節點是多的, 會造成應該輸出-1, 而我輸出某個值的情況.

問題

洛谷, libreoj的scanf, printf全都錯誤, 迴圈進不去…

思路

用一顆fhq-treap維護以工資值排序的序列, 在記錄乙個表示工資增減的變數delta, 就是說treap中的工資 + delta 才是真正的工資. 這樣我們在插入節點時, 我們要減去delta的影響. 查詢的時候也要減去delta的影響, 當然第k大的工資要加上delta的影響.

刪除操作只在s操作時會發生, 這時候把低於minlimit - delta的節點分離出來, 直接不管不需要逐個delete(這裡資料允許).

#include

#include

#include

#include

<

queue

>

#include

<

stack

>

#include

<

set>

#include

#include

#include

#include

using namespace std;

struct treap;

treap(treap * l, treap * r, int v, int p): left(l), right(r), value(v), priority(p);

void maintain()

};treap *

null

=new treap(), * root =

null;

typedef pair

ptt;

ptt split_l(treap * o, int val)

ptt result;

if(o->value <= val)

else

return result;

}ptt split_r(treap * o, int val)

ptt result;

if(o->value < val)

else

return result;

}treap * merge(treap * left, treap * right)

if(right ==

null)

if(left->priority < right->priority)

else

}int findkth(treap * o, int k)

if(k <= o->left->size)

if(k == o->left->size +

1) return findkth(o->right, k - o->left->size -

1);}

void insert(int val)

void print(treap * o)

print(o->left);

printf(" %d ", o->value);

print(o->right);

}int main()

else

break;

case

'i':

if(k < minlimit)

insert(k - salary);

break;

case

's':

salary -= k;

ptt tree = split_r(root, minlimit - salary);

cnt += tree.first->size;

root = tree.second;

break;}}

cout << cnt << endl;

return

0;}

洛谷P1486 鬱悶的出納員

題目大意 維護乙個平衡樹,支援插入乙個數,刪除小於乙個值的所有數,k 大值查詢,每個節點權值加減乙個數。題解 所有節點權值加減操作可以考慮直接維護乙個全域性標記,刪除小於乙個值的所有數字為乙個二分的過程,複雜度為 o logn 具體做法為 若當前子樹根節點權值小於 x,則直接刪除整顆左子樹,繼續遍歷...

假spaly害人 洛谷P1486 鬱悶的出納員

我以前的spaly他媽全抄模版的,然後覺得這樣太頹廢了,就很裝逼地想自己寫這題 其實我理論都懂的,所以我就認為自己應該何以靠自己的力量去做出來 然後做了兩個晚上 1h的在校時間 算算有6,7個小時呢 真日了狗了 網上的模版反正爛大街的,這道題hzwer的spaly寫的很爛的,結果過了 bz過了,洛谷...

洛谷P1486 鬱悶的出納員 Treap

oier公司是一家大型專業化軟體公司,有著數以萬計的員工。作為一名出納員,我的任務之一便是統計每位員工的工資。這本來是乙份不錯的工作,但是令人鬱悶的是,我們的老闆反覆無常,經常調整員工的工資。如果他心情好,就可能把每位員工的工資加上乙個相同的量。反之,如果心情不好,就可能把他們的工資扣除乙個相同的量...