可持久化陣列(可持久化線段樹 平衡樹)

2022-05-11 11:43:00 字數 1987 閱讀 3778

update : 最後乙個點時間空間已經放大

標題即題意

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

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

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

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

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

輸入格式:

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

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

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

對於操作1,格式為vi 1 loci valuei v_i \ 1 \ _i \ _i v​i​​1loc​i​​value​i​​,即為在版本vi v_i v​i​​的基礎上,將 aloci a__i} a​loc​i​​​​ 修改為 valuei _i value​i​​

對於操作2,格式為vi 2 loci v_i \ 2 \ _i v​i​​2loc​i​​,即訪問版本vi v_i v​i​​中的 aloci a__i} a​loc​i​​​​的值

輸出格式:

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

輸入樣例#1:

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

輸出樣例#1:

59

8741

8788

46

1 #include2 #include3 #include4 #include5

using

namespace

std;

6const

int n=1000000;7

struct

node

8s[n*20],*pos=s;

12 node *root[n+5

];13

int a[n+5],b[n+5],n,m,sz,rem[n+5

];14

void build(node* &rt,int l,int

r)15

21int mid=(l+r)/2

;22 build(rt->ch[0

],l,mid);

23 build(rt->ch[1],mid+1

,r);24}

25void insert(node* &rt,int l,int r,int k,int

w)26

35int mid=(l+r)/2;36

if (k<=mid) insert(rt->ch[0

],l,mid,k,w);

37else insert(rt->ch[1],mid+1

,r,k,w);38}

39int query(node* rt,int l,int r,int

k)40

46int

main()

47 54 build(root[0],1

,n);

55for (i=1;i<=m;i++)

5664

else

6570

}71 }

模板 可持久化陣列(可持久化線段樹 平衡樹)

update 最後乙個點時間空間已經放大 標題即題意 有了可持久化陣列,便可以實現很多衍生的可持久化功能 例如 可持久化並查集 如題,你需要維護這樣的乙個長度為 n n n 的陣列,支援如下幾種操作 在某個歷史版本上修改某乙個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作 對於操...

可持久化線段樹(主席樹)及可持久化陣列

定義 可以訪問歷史版本的線段樹為可持久化線段樹 可持久化線段樹之所以可以訪問歷史版本,是因為巨集觀上看,它為每個版本維護了一棵樹。當然,如果真的對每個版本建一顆樹,時間空間複雜度都hold不住。所以建立i版本的樹時,如果某顆子樹相對於i 1版本沒有變化,就可以直接使其父親對應的指標指向i 1版本的這...

可持久化平衡樹

如題。大家都知道,用權值線段樹可以過普通平衡樹那道題,那麼對於可持久化普通平衡樹,我們是否也可以用主席樹來搞一搞呢。答案是肯定的。只需要動態開點就行了。其他的跟普通平衡樹那道題一模一樣。這裡需要注意一點,當 l 和 r 都是負數的時候,2 就會有問題,因為 5 2 2 而 5 1 3 所以除2會使 ...