請你寫出一種資料結構,來維護乙個長度為 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小的...