可持久化線段樹就是包含歷史狀態的線段樹;我們需要用動態開點的方式來記錄左右兒子。
如果當前左右兒子不發生變化,我們就直接使用上乙個歷史版本的左右兒子;否則新建節點即可。
建立n#include
#include
#include
#include
#include
#include
#include
using
namespace std;
int n,m,t;
int cnt =0;
int c[
20000];
int root[
200000];
struct segmenttree a[
10000000];
inline
intread
(void
)while
(c>=
'0'&& c<=
'9') s = s*
10+c-
48,c =
getchar()
;return s*w;
}void
build
(int
&root,
int l,
int r)
int mid = l+r >>1;
if(l <= mid)
build
(a[root]
.lc,l,mid);if
(r > mid)
build
(a[root]
.rc,mid+
1,r)
; a[root]
.ans =
max(a[a[root]
.lc]
.ans,a[a[root]
.rc]
.ans)
;return;}
void
change
(int
&root,
int pre,
int p,
int v,
int l,
int r)
int mid = l+r >>1;
if(p <= mid)
change
(a[root]
.lc,a[pre]
.lc,p,v,l,mid);if
(p > mid)
change
(a[root]
.rc,a[pre]
.rc,p,v,mid+
1,r)
; a[root]
.ans =
max(a[a[root]
.lc]
.ans,a[a[root]
.rc]
.ans)
;return;}
intask
(int root,
int askl,
int askr,
int l,
int r)
intmain
(void
)return0;
}
nn棵線段樹,第i棵線段樹的數字是1−i
1-i1−
i,而且需要可持久化來記錄歷史版本。
對於[ l,
r]
[l,r]
[l,r
]的詢問,其實可以轉化為第r
rr棵線段樹−
-−第l
ll棵線段樹的第k
kk大,我們就可以遞迴來查詢區間第k
kk小。
去過左區間》
k>k
>
k,就在左區間查詢;否則就在右區間查詢k−s
ize[
l]
k-size[l]
k−size
[l]小即可。
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
int n,m;
struct tree
a[20000000];
struct node
} c[
1000000];
int cnt =0;
int ans[
200000];
int root[
200000];
bool
cmp(node p1,node p2)
inline
intread
(void
)while
(c>=
'0'&& c<=
'9') s = s*
10+c-
48,c =
getchar()
;return s*w;
}void
build
(int
&root,
int pre,
int l,
int r,
int pos)
intask
(int root1,
int root2,
int l,
int r,
int k)
intmain
(void
)sort
(c+1
, c+n+
1, cmp)
;for
(int i=
1;i<=n;
++i)
build
(root[i]
,root[i-1]
,1,n,c[i]
.num)
;for
(int i=
1;i<=m;
++i)
return0;
}
可持久化線段樹(主席樹)模板
題目背景 這是個非常經典的主席樹入門題 靜態區間第k小 資料已經過加強,請使用主席樹。同時請注意常數優化 題目描述 如題,給定n個正整數構成的序列,將對於指定的閉區間查詢其區間內的第k小值。輸入輸出格式 輸入格式 第一行包含兩個正整數n m,分別表示序列的長度和查詢的個數。第二行包含n個正整數,表示...
模板 可持久化線段樹 主席樹
這是一道非常直白的可持久化線段樹的練習題,目的並不是虐人,而是指導你入門可持久化資料結構。線段樹有個非常經典的應用是處理rmq問題,即區間最大 最小值詢問問題。現在我們把這個問題可持久化一下 q k l r 查詢數列在第k個版本時,區間 l,r 上的最大值 m k p v 把數列在第k個版本時的第p...
模板 可持久化線段樹 (主席樹)
這是個非常經典的主席樹入門題 靜態區間第k小。基本思想是像維護字首和一樣,維護每個區間 1.i 中的數,在 1.j 範圍的數的個數。因為大多數狀態是重複的所以我們並不需要開 n 個線段樹,只需要連線到一些沒有改變的子狀態上就可以了。對於查詢區間 ql.qr 內第 k 小的,我們可以判斷,對於當前結點...