洛谷P3919可持久化線段樹

2021-08-25 12:00:46 字數 3181 閱讀 1908

有了可持久化陣列,便可以實現很多衍生的可持久化功能(例如:可持久化並查集)

如題,你需要維護這樣的乙個長度為 n 的陣列,支援如下幾種操作

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

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

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

輸入格式:

輸入的第一行包含兩個正整數 n m, 分別表示陣列的長度和操作的個數。

第二行包含 n 個整數,依次為初始狀態下陣列各位的值(依次為 ai ,1 ≤ i ≤ n)。

接下來 m行每行包含 3 或 4 個整數,代表兩種操作之一( i 為基於的歷史版本號):

1.對於操作1,格式為 vi 1 loci valuei,即為在版本 vi 的基礎上,將 aloci 修改為 valuei。

2.對於操作2,格式為 vi 2 loci,即訪問版本 vi 中的 aloci 的值。

(1 <= n,m <= 105,1 <= loci <= n,1 <= vi <= i,- 109 <= ai,valuei <= 109)

輸出格式:

輸出包含若干行,依次為每個操作2的結果。

5 10

59 46 14 87 41

0 2 1

0 1 1 14

0 1 1 57

0 1 1 88

4 2 4

0 2 5

0 2 4

4 2 1

2 2 2

1 1 5 91

59

8741

8788

46

說明樣例說明:

一共11個版本,編號從0-10,依次為:

*0: 59 46 14 87 41

*1: 59 46 14 87 41

*2: 14 46 14 87 41

*3: 57 46 14 87 41

*4: 88 46 14 87 41

*5: 88 46 14 87 41

*6: 59 46 14 87 41

*7: 59 46 14 87 41

*8: 88 46 14 87 41

*9: 14 46 14 87 41

*10: 59 46 14 87 91

給出 n 個數字的序列,m 次操作。

有兩個操作: 1. 更新 i 點元素為 k,並儲存版本 +1。

2. 查詢 x 版本下點 i 的值。 起初為版本號為 0。

可持久化線段樹最大的特點是:

由於可持續化線段樹的結點的序號不確定。 因此需要採取動態開點的方法構建線段樹

struct nodesegtree[maxn << 8];//可持久化線段樹

int root[maxn << 5];//root[i]表示版本號為i的線段樹的根節點編號

long long int a[maxn];//長度為 n 的陣列

int n,m;//n個點,m種操作

int tot;

int build_tree(int l, int r)

int mid = l + (r - l)/2;

segtree[pos].lc = build_tree(l, mid);

segtree[pos].rc = build_tree(mid + 1, r);

return pos;

}//即訪問版本 pos 中的 a[p] 的值

long long int query(int pos, int p, int l, int r)

int mid = l + (r - l)/2;

if(p <= mid) return query(segtree[pos].lc, p, l, mid);

else return query(segtree[pos].rc, p, mid + 1, r);

}//在版本 old 的基礎上,將 a[tar] 修改為 c

int update(int old, int tar, int c, int l, int r)

segtree[pos].lc = segtree[old].lc;

segtree[pos].rc = segtree[old].rc;

int mid = l + (r - l)/2;

if(tar <= mid) segtree[pos].lc = update(segtree[old].lc, tar, c, l, mid);

else segtree[pos].rc = update(segtree[old].rc, tar, c, mid + 1, r);

return pos;}

int main()

root[0] = build_tree(1,n);

int v,x,l,w;

for (int i = 1;i <= m; i++) else

}} return 0;

}

洛谷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表示初始...