NOI2004 鬱悶的出納員 SBT

2021-06-08 01:52:14 字數 1360 閱讀 3440

by---cxlove

splay tree寫了4、5個小時,debug不能,只有跪舔啊。

改用sbt,還是sb tree好用。。。

把乙個變數用作類似線段樹中的延遲標記,不需要在每次加或者減的時候進行全部更新。在後來插入的結點中,應該當之前的延遲算進去,如果初始就小於下限的不新增,而且也不算作最後離開的人數。

在刪除的時候,如果根結點小於下限,說明左子樹以及根結點都小於下限,直接把右子樹作為根。對新的樹進行處理。

如果根結點大於下限,說明右子樹也全部大於下限,對左子樹進行處理,最後更新根的size。

#include#include#include#include#define n 100005

using namespace std;

struct sbt

}t[n];

int root,tot; //根的位置以及節點個數

//左旋轉處理

void left_rot(int &x)

//右旋轉處理

void right_rot(int &x)

//調整處理

void maintain(int &r,bool flag)

else

return;

} else

else

return;

} //更新子樹,然後再更新根,直到平衡為止

maintain(t[r].left,false);

maintain(t[r].right,true);

maintain(r,false);

maintain(r,true);

}//插入新節點

void insert(int &r,int k)

else

}//刪除結點,利用的是前驅替換

int remove(int &r,int k)

else remove(kt[r].key)

get_pre(t[r].right,r,k);

else

get_pre(t[r].left,y,k);

}//獲得後繼

int get_next(int &r,int y,int k)

//排序

void inorder(int &r)

int main(){

int q,delay,miv_val;

while(scanf("%d%d",&q,&miv_val)!=eof){

tot=delay=root=0;

while(q--){

char str[10];

int k;

scanf("%s%d",str,&k);

if(str[0]=='i'){

if(k

noi 2004 鬱悶的出納員

原題位址 花了一兩天真正的熟悉了treap,對於乙個東西,本蒟蒻認為,不應該要會,還應會熟練的寫,像哈狗寫這個只需十分鐘 好吧,話歸正題 先推薦另類解法 戳進去 此題解法很多bit 權值線段樹 各種平衡樹 準備抽空寫 是一道很棒的模板題。這道題我們把每次全體加的工資和減的弄到乙個變數,姑且叫為w,把...

NOI2004 鬱悶的出納員

大致題意就是對初始為空的數列的各種操作233 題解 splay啦 其中可能會遇到的幾個問題 1.如何刪去低於min的點 找到數列中min的後繼提為根,把根的左孩子丟 shan 了就完成了 很容易yy到的對吧 2.如何處理對當前數列中的數進行 k 開個全域性變數存整體的波動 值ff。那麼刪點的時候就把...

NOI2004 鬱悶的出納員

點此看題 這道題很新的一點就是加工資和減工資,這貌似要用到區間修改。但是細細想想,操作的物件是全樹,我們可以維護乙個累積的修改值,新加入乙個點的話要刪去之前的累計的修改值,對於減工資的情況,判斷有沒有低於最低的限制。注意如果乙個一來人就低於最低線,那麼這個人不被統計在最後的刪除人數中。include...