洛谷 1486 鬱悶的出納員 Treap

2022-09-06 17:27:16 字數 1468 閱讀 5807

【題意概述】

要求維護乙個序列支援以下操作:

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 #include3

#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 }

view code

洛谷P1486 鬱悶的出納員

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

洛谷P1486 鬱悶的出納員 Treap

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

luogu1486 鬱悶的出納員

題目鏈結 這個題其實就是對於treap中的刪除操作進行一些修改。自己yy了一種做法。就是在刪除的時候,如果要刪除的數比這棵子樹的根大,那麼就把根變成根的右孩子,這樣就相當於刪除了整棵左子樹和根節點。然後重新維護一下siz,並且維護一下平衡性就行了。竟然把rotate函式寫錯了。調了30min。又沒正...