可持久化線段樹可以將歷史版本的線段樹記憶下來,並支援新建版本與查詢歷史版本。
其中有一道經典的靜態主席樹的題就是求區間k大。
建樹的過程其實就是先建一棵空樹,再按輸入順序插入節點。需要新開節點的時候就新開,如果和之前沒有什麼變化的話就連到之前的樹上。這樣的空間複雜度據說是θ(nlogn)
由於線段樹支援區間減法,於是我們可以在查詢區間的時候利用字首和的思想,對於[l,r]的區間,我們可以讓第l-1個線段樹與第r個線段樹相減。
**如下:(附有較詳細的注釋。)
1//writer : hsz %wjmzbmr%tourist%hzwer
2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include
9 #include 10 #include 11 #include 12 #include 13
#define ll long long
14using
namespace
std;
15const
int n=200005
<<5;16
int l[n],r[n],sum[n],b[n];//
sum表示線段樹區間內點的數量。
17int
n,m,a[n],root[n],tot;
18int build(int l,int
r) 24
return
rt;25}26
int update(int pre,int l,int r,int c)
33return rt;//
返回新建子樹的根節點。34}
35int query(int u,int v,int l,int r,int
k) 43
intmain()
53int
q,v,k;
54for(int i=1; i<=m; i++)
58return0;
59 }
主席樹(可持久化線段樹)
我真弱。連主席樹都不會。主席樹相當於多個線段樹,由於相鄰兩棵線段樹的節點的值只有少許不同,因此可以對於和前一棵樹一樣的子樹乙個指標指過去,無需操作,這樣每棵樹o logn 總複雜度o nlogn 以下是區間k大 include include include define n 100005 defi...
主席樹 可持久化線段樹
首先要學會普通的線段樹,然後理解權值線段樹,而主席樹就是多個權值線段樹 我自己的理解 但是這多個權值線段樹之間有公共部分,節約了空間。它一開始是乙個空樹,後來逐個添數,記錄新增的這個數在那個範圍內,並 1,顯然它每次只更新了一條鏈,其他不需要變,這樣就有了多個版本的線段樹。如果求 l,r 範圍內第k...
可持久化線段樹(主席樹)
qwq我大概又是機房最後乙個學主席樹的了吧 其實之前一直都在講 只是沒做題 做了幾道以後發現都是乙個套路qwq關鍵就是能不能看出來要用主席樹 主要可以解決 靜態 動態區間第k大 樹上也可以 一些有關區間的帶某些限制的詢問 如出現次數等 先把模板粘上來 include include include ...