可持久化資料結構c

2021-09-06 06:35:34 字數 2589 閱讀 9444

可持久化資料結構的原理在於,每次修改創造乙個新節點作為根,對修改部分再創一條鏈,對於未修改部分直接連向上次修改連向的位置,這樣,就可以在較小的空間儲存每次修改時的狀態.

以可持久化字典樹為例

如果我們要加入cat,cap,rat,cute,等詞

第一步

然後,再插入第二個單詞

可以看到,新建一棵樹存當前的詞,然後連向之前已經有過的樹

第三第四個單詞

以上就是可持久化字典樹的內容

可持久化線段樹同理

每次修改新增一條,剩下的直接連向之前的

最大異或和( ) 洛谷p4735

每次將字首和的二進位制形式加入到0/1字典樹中

詢問時優先詢問與某關鍵值(x^s[n])相反的路徑

從高位到低位儲存和詢問

因為0/1字典樹是二叉的,所以連向上一段的已有子樹可以直接連線

陣列解釋

int trie[maxn*24]

[2],latest[maxn*24]

;//字典樹;當前結點向下傳遞的最後乙個字首和的位置編號

//位置編號就是指插入的順序編號

int s[maxn]

,root[maxn]

,n,m,tot;

//字首和;根據更改先後變化的根節點

以下是插入操作

void

insert

(int i,

int k,

int p,

int q)

//第i個字首和,二進位制從低到高第k位,p為上一段同深度端點,q為當前端點

int c=s[i]

>>k&1;

if(p) trie[q]

[c^1

]=trie[p]

[c^1];

//如果上一段有平行的對應結點則連線

trie[q]

[c]=

++tot;

//新建結點

insert

(i,k-

1,trie[p]

[c],trie[q]

[c])

;//插入下乙個結點

latest[q]

=max

(latest[trie[q][0

]],latest[trie[q][1

]]);

//向下最大的末位字首和位置編號

}

以下是完整**

#include

#include

#include

#include

#define r rein()

#define lr lrein()

#define ll long long int

#define ri register int

inline

int r

inline ll lr

using

namespace std;

const

int deviation=10;

const

int maxn=

3e5+deviation;

int trie[maxn*24]

[2],latest[maxn*24]

;int s[maxn]

,root[maxn]

,n,m,tot;

void

insert

(int i,

int k,

int p,

int q)

int c=s[i]

>>k&1;

if(p) trie[q]

[c^1

]=trie[p]

[c^1];

trie[q]

[c]=

++tot;

insert

(i,k-

1,trie[p]

[c],trie[q]

[c])

; latest[q]

=max

(latest[trie[q][0

]],latest[trie[q][1

]]);

}int

ask(

int now,

int val,

int k,

int limit)

intmain()

}return0;

}

可持久化資料結構

1.可持久化線段樹 可持久化陣列 最基礎的可持久化資料結構,每次修改開新的log個點即可。includeusing namespace std const int n 1e6 100 templatevoid rd t x templatevoid print t x struct segseg n...

可持久化資料結構

用vector實現可持久化 這題要求的是乙個支援區間查詢的可持久化資料結構。這裡使用vector巧妙地實現 pair用pair儲存時間戳以及當前時間的值,query的時候使用二分查詢即可。如下 1 include2 include3 include4 include5 define x first ...

可持久化資料結構維護可持久化陣列

首先我們要知道,undo 操作,也就是直接跳回前面的操作 歷史操作 然後跳回的地方到現在的地方這乙個區間的操作都不用管。這就是高階挑戰的思路 可持久化是指一種可以訪問歷史版本的資料結構 然後我們就可以知道,詢問歷史,又是陣列,也就是可持久化陣列。可持久化陣列的維護很簡單,我們可以開乙個 o n 2 ...