可持久化線段樹(主席樹)

2022-04-09 11:31:42 字數 1027 閱讀 8308

可持久化線段樹可以將歷史版本的線段樹記憶下來,並支援新建版本與查詢歷史版本。

其中有一道經典的靜態主席樹的題就是求區間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 ...