日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ1503[NOI2004]郁闷的出纳员——treap

發布時間:2024/9/21 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ1503[NOI2004]郁闷的出纳员——treap 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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。

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

輸入樣例#1:? 9 10 I 60 I 70 S 50 F 2 I 30 S 15 A 5 F 1 F 2 輸出樣例#1:? 10 20 -1 2

說明

I命令的條數不超過100000

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

F命令的條數不超過100000

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

新員工的工資不超過100000

這道題是一道經典的平衡樹練習題,題中一共有四種操作:插入,查詢,修改(上調和下降)。

這里面唯一和一般的treap不一樣的操作就是修改,如果每一次都把每個數加上或減掉一個值顯然是不行的,但我們發現每次修改都是對全體修改,那么我們就可以不進行修改,相對的把工資下界調整,這樣也就相當于修改了每個員工的工資。

但是如果在某次漲工資之后來了一名員工,他并沒有趕上漲工資,如果他的工資大于初始工資下界(這樣才能進來)但卻小于當前工資下界,那么下一次降工資后他本來不會跳槽(下降之后仍大于初始工資下界),卻因為小于當前工資下界,那他到底會不會跳槽呢?依據題意是不會的,但如果按上述做法就是會跳槽的。那么就要在他剛進公司時我們要先給他加上之前漲的工資(使他工資一定大于當前工資下界),在查詢到他時再減掉就可以了。

工資下降相當于工資下界上調,這樣就有可能有人會跳槽,因為I命令不超過10^5,樹中最多不會超過10^5個節點,刪除點個數也不會超過這些,所以暴力刪除就好。

如果查前驅函數是void函數要記得每次查詢之后把answer歸零。

#include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<ctime> #include<cstring> using namespace std; int r[100010]; int v[100010]; int w[100010]; int ls[100010]; int rs[100010]; int size[100010]; int tot; int root; int n,m; int del; int mini; int x; char a[10]; int answer; int ans; void up(int x) {size[x]=size[rs[x]]+size[ls[x]]+w[x]; } void rturn(int &x) {int t;t=ls[x];ls[x]=rs[t];rs[t]=x;size[t]=size[x];up(x);x=t; } void lturn(int &x) {int t;t=rs[x];rs[x]=ls[t];ls[t]=x;size[t]=size[x];up(x);x=t; } void insert_sum(int x,int &i) {if(!i){i=++tot;w[i]=size[i]=1;v[i]=x;r[i]=rand();return ;}size[i]++;if(x==v[i]){w[i]++;}else if(x>v[i]){insert_sum(x,rs[i]);if(r[rs[i]]<r[i]){lturn(i);}}else{insert_sum(x,ls[i]);if(r[ls[i]]<r[i]) {rturn(i);}}return ; } void delete_sum(int x,int &i) {if(i==0){return ;}if(v[i]==x){if(w[i]>1){w[i]--;size[i]--;return ;}if((ls[i]*rs[i])==0){i=ls[i]+rs[i];}else if(r[ls[i]]<r[rs[i]]){rturn(i);delete_sum(x,i);}else{lturn(i);delete_sum(x,i);}return ;}size[i]--;if(v[i]<x){delete_sum(x,rs[i]);}else{delete_sum(x,ls[i]);}return ; } int ask_sum(int x,int i) {if(i==0){return 0;}if(x>size[ls[i]]+w[i]){return ask_sum(x-size[ls[i]]-w[i],rs[i]);}else if(size[ls[i]]>=x){return ask_sum(x,ls[i]);}else{return v[i];} } void ask_front(int x,int i) {if(i==0){return ;}if(v[i]<x){answer=i;ask_front(x,rs[i]);return ;}else{ask_front(x,ls[i]);return ;}return ; } int main() {srand(12378);scanf("%d%d",&n,&m);mini=m;for(int i=1;i<=n;i++){scanf("%s",a+1);scanf("%d",&x);if(a[1]=='I'){if(x>=mini){insert_sum(x-del,root);}}else if(a[1]=='A'){m-=x;del+=x;}else if(a[1]=='S'){m+=x;del-=x;answer=0;ask_front(m,root);while(answer!=0){delete_sum(v[answer],root);ans++;answer=0;ask_front(m,root);}}else if(a[1]=='F'){if(size[root]-x+1>0){printf("%d\n",ask_sum(size[root]-x+1,root)+del);}else{printf("-1\n");}}}printf("%d",ans); }

轉載于:https://www.cnblogs.com/Khada-Jhin/p/8987211.html

總結

以上是生活随笔為你收集整理的BZOJ1503[NOI2004]郁闷的出纳员——treap的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。