洛谷P3919 模板 可持久化陣列 主席樹

2022-09-01 10:30:15 字數 1549 閱讀 3652

題目連線:

如題,你需要維護這樣的乙個長度為n

n的陣列,支援如下幾種操作

在某個歷史版本上修改某乙個位置上的值

訪問某個歷史版本上的某一位置的值

此外,每進行一次操作(對於操作2,即為生成乙個完全一樣的版本,不作任何改動),就會生成乙個新的版本。版本編號即為當前操作的編號(從1開始編號,版本0表示初始狀態陣列)

主席樹模板題。

主席樹的題目大多是單點修改的。當我們需要支援訪問歷史版本時,最簡單的方法是新建一棵線段樹。

但是這樣的記憶體會**的。

我們發現,由於只要單點修改,所以我們需要修改的就只有這個節點以及他的祖宗,其他點就是根本不用修改的,所以如果我們可以只修改需要修改的點,其他點直接連向原本線段樹的點,就可以大大壓縮空間。雖然這樣空間複雜度還是會很高

假設我們有一棵這樣的線段樹

其中l,rl

,r分別表示左兒子和右兒子。

此時如果我們需要修改點10,就可以得到下面這樣一棵主席樹

注意節點13,14的左兒子和右兒子的位置還是不變的。

此時如果我們需要訪問歷史版本0,就從根節點1為的主席樹找,如果要訪問歷史版本1,就從根及誒單為12的主席樹找。

這樣的時間複雜度是o(m

logn

)o(m

logn

),空間複雜度是o(n

+mlo

gn)o

(n+m

logn

)。為了節省空間,主席樹的區間表示不再在結構體中記錄,而是使用遞迴引數來傳遞。

#include

using

namespace std;

const

int n=

1e6+10;

const

int m=n+

20*n;

int n,m,a[n]

,root[n]

,tot,s,k,val,x;

struct tree

tree[m*2]

;int

build

(int l,

int r)

return p;

}int

change

(int now,

int l,

int r,

int k,

int val)

//修改

return p;

}int

ask(

int now,

int l,

int r,

int k)

//查詢

return p;

}int

main()

else

}return0;

}

洛谷P3919 模板 可持久化陣列

題目大意 有兩個操作,1 在第x次操作後的版本上修改乙個值,2 查詢在第x次操作後的版本上的乙個節點的值 即 你需要維護這樣的乙個長度為n的陣列,支援如下幾種操作 1.在某個歷史版本上修改某乙個位置上的值 2.訪問某個歷史版本上的某一位置的值 此外,每進行一次操作 對於操作2,即為生成乙個完全一樣的...

洛谷P3919 可持久化陣列

題目大意 需要維護乙個長度為 n 的陣列,支援在歷史版本上單點修改和單點查詢。題解 顯然,如果直接暴力維護的話會 mle。因此,採用線段樹進行維護,使得空間複雜度由 o mn 降至 o mlogn 不過相應的時間複雜度由 o 1 上公升至 o logn 如下 include using namesp...

洛谷P3919可持久化線段樹

有了可持久化陣列,便可以實現很多衍生的可持久化功能 例如 可持久化並查集 如題,你需要維護這樣的乙個長度為 n 的陣列,支援如下幾種操作 在某個歷史版本上修改某乙個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作 對於操作2,即為生成乙個完全一樣的版本,不作任何改動 就會生成乙個新...