樹套樹 線段樹套set

2021-10-09 14:47:13 字數 1877 閱讀 6695

請你寫出一種資料結構,來維護乙個長度為 n 的序列,其中需要提供以下操作:

1 pos x,將 pos 位置的數修改為 x。

2 l r x,查詢整數 x 在區間 [l,r] 內的前驅(前驅定義為小於 x,且最大的數)。

數列中的位置從左到右依次標號為 1∼n。

區間 [l,r] 表示從位置 l 到位置 r 之間(包括兩端點)的所有數字。

區間內排名為 k 的值指區間內從小到大排在第 k 位的數值。(位次從 1 開始)

輸入格式

第一行包含兩個整數 n,m,表示數列長度以及操作次數。

第二行包含 n 個整數,表示有序數列。

接下來 m 行,每行包含乙個操作指令,格式如題目所述。

輸出格式

對於所有操作 2,每個操作輸出乙個查詢結果,每個結果佔一行。

資料範圍

1≤n,m≤5×104,

1≤l≤r≤n,

1≤pos≤n,

0≤x≤108,

有序數列中的數字始終滿足在 [0,108] 範圍內,

資料保證所有操作一定合法,所有查詢一定有解。

輸入樣例:

5 33 4 2 1 5

2 2 4 4

1 3 5

2 2 4 4

輸出樣例:21

每個區間套乙個set。

#include

//#define int long long

#define lson u<<1

#define rson u<<1|1

using

namespace std;

//const int mod=1e9+7;

const

int inf=

1e9;

const

int n=

5e4+10;

int w[n]

;struct node

}tr[n<<2]

;void

build

(int u,

int l,

int r)

; tr[u]

.st.

insert

(-inf)

,tr[u]

.st.

insert

(inf)

;for

(int i=l;i<=r;i++

) tr[u]

.st.

insert

(w[i]);

if(l==r)

return

;int mid=l+r>>1;

build

(lson,l,mid)

;build

(rson,mid+

1,r);}

void

update

(int u,

int pos,

int x)

intquery

(int u,

int l,

int r,

int x)

int mid=tr[u]

.mid()

,res=

-inf;

if(l<=mid) res=

max(res,

query

(lson,l,r,x));

if(r>mid) res=

max(res,

query

(rson,l,r,x));

return res;

}void

solve()

else

if(op==2)

}return;}

signed

main()

初學樹套樹 線段樹套Treap

樹套樹是乙個十分神奇的演算法,種類也有很多 像什麼樹狀陣列套主席樹 樹狀陣列套值域線段樹 zkw 線段樹套 vector 等等。不過,像我這麼弱,當然只會最經典的線段樹套 treap 啦。線段樹我相信大家都會的,treap 可以看一下這篇部落格 簡析平衡樹 二 treap 線段樹套 treap 的思...

POJ 2155 樹套樹 線段樹套線段樹

matrix 樓教主出的題目。題意 乙個矩陣初始值都為0,每次給 c x1 y1 x2 y2 去反轉這個矩陣。或者 q x1 y1 查詢這個點是0 1。第一次接觸樹套樹的題目。一句ac 對於基本的線段樹,再在每個節點建乙個y方向上的線段樹。tree n m 這道題目更新的時候,對於x方向就是 x1,...

二逼平衡樹 樹套樹(線段樹套Splay平衡樹)

題面 bzoj3196 解析線段樹和splay兩棵樹套在一起,常數直逼inf,但最終僥倖過了 思路還是比較簡單,在原陣列維護乙個下標線段樹,再在每乙個線段樹節點,維護乙個對應區間的權值splay。簡單說一下操作 0.提取區間 1.查詢區間內k的排名 提取區間,找到區間內所有的splay,分別比k小的...