【題意概述】
要求維護乙個序列支援以下操作:
1,插入元素x;
2,把序列的所有元素加上x;
3,把序列的所有元素減去x,同時低於乙個給定的下限的元素馬上被刪除;
4,詢問序列中第k大的元素。
【題解】
treap
用乙個delta記錄元素的增減情況,即實際上的元素的值應該是qval(root,x)+delta,那麼插入元素時插入的應該是val-delta.
每次加減操作的時候改delta和下限minwage,加操作的時候minwage-=val(即下限相對於元素值減小了val),減操作的時候minwage+=val(即下限相對於元素值增加了val)
每次減操作時**出序列裡小於minwage的元素,把它們扔掉即可。
1 #include2 #include3view code#define ls (a[u].l)
4#define rs (a[u].r)
5using
namespace
std;
6const
int maxn=200010;7
intn,k,x,y,z,v,tot,root,minwage,minnow,delta;
8char
c,c2;
9struct treapa[maxn];
10 inline int
read()
16void newnode(int val);}
17void update(int u)
18void split(int u,int k,int &x,int &y)
20if(a[u].size==k)
21if(a[ls].size>=k) split(ls,k,x,ls),y=u;
22else split(rs,k-a[ls].size-1,rs,y),x=u;
23update(u);24}
25int merge(int x,int
y)28
else29}
30int qrank(int u,int
val)
34int qval(int u,int
k)38
intmain()
49if(c=='
a') minnow-=v,delta+=v;
50if(c=='s'
)55if(c=='
f') printf("
%d\n
",a[root].size>=v?qval(root,a[root].size-v+1)+delta:-1
);56}57
return printf("
%d",tot-a[root].size),0
;58 }
洛谷P1486 鬱悶的出納員
題目大意 維護乙個平衡樹,支援插入乙個數,刪除小於乙個值的所有數,k 大值查詢,每個節點權值加減乙個數。題解 所有節點權值加減操作可以考慮直接維護乙個全域性標記,刪除小於乙個值的所有數字為乙個二分的過程,複雜度為 o logn 具體做法為 若當前子樹根節點權值小於 x,則直接刪除整顆左子樹,繼續遍歷...
洛谷P1486 鬱悶的出納員 Treap
oier公司是一家大型專業化軟體公司,有著數以萬計的員工。作為一名出納員,我的任務之一便是統計每位員工的工資。這本來是乙份不錯的工作,但是令人鬱悶的是,我們的老闆反覆無常,經常調整員工的工資。如果他心情好,就可能把每位員工的工資加上乙個相同的量。反之,如果心情不好,就可能把他們的工資扣除乙個相同的量...
luogu1486 鬱悶的出納員
題目鏈結 這個題其實就是對於treap中的刪除操作進行一些修改。自己yy了一種做法。就是在刪除的時候,如果要刪除的數比這棵子樹的根大,那麼就把根變成根的右孩子,這樣就相當於刪除了整棵左子樹和根節點。然後重新維護一下siz,並且維護一下平衡性就行了。竟然把rotate函式寫錯了。調了30min。又沒正...