可持久化陣列 洛谷3919

2021-10-01 21:51:14 字數 3108 閱讀 4975

最近一直在搞資料結構,主席樹,理解也不算特別深刻,還沒有對動態開點和可持久化思想理解特別深刻,所以,今天我就準備寫一篇可持久化陣列來通一通腦子

新手入門題目:洛谷:可持久化陣列

就題論題:

給乙個陣列a[ ]:我們可以對其進行修改,然後詢問不同版本的值,最初的版本為:0,修改一次就產生乙個新版本

樸素做法:

寫乙個二維陣列ver[i][j]i代表版本,然後尋問 第i個版本第pos個位置的值,這樣對於小資料來說還行,不會mle,也不會tle,但是對於大資料來說,每次修改都是o(n),修改m次,時間複雜度為o(nm),而且大資料會mle,ver[10^6][10^4]毫無疑問陣列存不下,那麼現在可持久化陣列出現了,可持久化陣列的實現利用了線段樹+可持久化思想

首先:我們建出最初版本的線段樹來存版本0的陣列,我們以陣列大小為5為例:

根據上圖,已經把圖建了出來了,也不怎麼耗費空間了,我們要查某乙個版本的陣列的值,只需要,知道某一版本的根節點即可

ac**:

#include

.h>

using namespace std;

//可持久化陣列

const

int maxn=

1e6+5;

int root[maxn]

;struct node

tr[maxn*40]

;int a[maxn]

;int cnt;

void

build

(int l,

int r,

int&now)

int mid=l+r>>1;

build

(l,mid,tr[now]

.l);

build

(mid+

1,r,tr[now]

.r);

}void

modify

(int l,

int r,

int per,

int&now,

int pos,

int w)

tr[now]

.l=tr[per]

.l; tr[now]

.r=tr[per]

.r;int mid=l+r>>1;

if(mid>=pos)

else

}int

query

(int l,

int r,

int ver,

int pos)

int mid=l+r>>1;

if(mid>=pos)

else

}int

main()

build(1

,n,root[0]

);int ver,op,pos,w,id=0;

for(

int i=

1;i<=q;i++

)else

}}

強調:

結構體中的l,r代表的是左右孩子節點,建樹過程中了l,r 代表的就是左右孩子節點,root[i],代表的是每乙個版本的根節點,通過根節點,可以找到這個版本的所有點,我們把當前版本和上一版本連起來即可

理解後打的**:

#include

.h>

using namespace std;

//可持久化陣列

const

int maxn=

1e6+5;

struct node

tr[maxn*40]

;int root[maxn]

;//根節點

int a[maxn]

;int cnt;

void

build

(int l,

int r,

int&now)

//建一顆初始版本的樹

int m=l+r>>1;

build

(l,m,tr[now]

.l);

build

(m+1

,r,tr[now]

.r);

}void

modify

(int l,

int r,

int ver,

int&now,

int pos,

int w)

//修改一顆樹

int m=l+r>>1;

if(m>=pos)

else

}int

query

(int l,

int r,

int ver,

int pos)

int m=l+r>>1;

if(m>=pos)

else

}int

main()

build(1

,n,root[0]

);int id=0;

while

(q--

)else

}}

洛谷P3919 可持久化陣列

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

洛谷P3919 模板 可持久化陣列

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

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

題目連線 如題,你需要維護這樣的乙個長度為n n的陣列,支援如下幾種操作 在某個歷史版本上修改某乙個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作 對於操作2,即為生成乙個完全一樣的版本,不作任何改動 就會生成乙個新的版本。版本編號即為當前操作的編號 從1開始編號,版本0表示初始...