模板 可持久化陣列

2021-08-20 01:42:37 字數 2955 閱讀 1015

戳我

為了方便起見,處理的陣列長度為5, 起始的陣列元素為1~5,修改是將第乙個位置的陣列元素改為2。

建樹規則很簡單,只要在葉子節點上寫上該點的值就可以了。

我們發現,這兩棵線段樹中只有乙個葉子節點的值發生了改變,而運算元非常多,假如每次都memset一下,然後修改乙個值,空間上的巨大開銷幾乎無法想象,那我們可以設想一下,把兩個線段樹「合併一下」……

這下我們的思路就很清楚了。每次對某個歷史版本進行修改時,對於所有包含該位置的區間結點全部新開乙個,並與其父節點連邊,對於其他結點,由於不需要發生改動,所以直接連線即可。

#include

#include

#include

#include

#include

#define maxn 2000005

int n, m, p, x, y, lastans;

int a[maxn];

inline

int getint()

while (ch >= '0' && ch <= '9')

num = (num << 3) + (num << 1) + (ch ^ '0'),

ch = getchar();

return num * sign;

}struct rope

int mid = (l + r) >> 1;

build(lc[k], l, mid);

build(rc[k], mid + 1, r);

} int query(int k, int l, int r, int pos)

void insert(int x, int &y, int l, int r, int pos, int val)

int mid = (l + r) >> 1;

lc[y] = lc[x]; rc[y] = rc[x]; //複製左子樹和右子樹,那些需要重開的結點會在接下來的遞迴被修改

if (pos <= mid)

insert(lc[x], lc[y], l, mid, pos, val);

else insert(rc[x], rc[y], mid + 1, r, pos, val);

} void build(int l, int r)

int find(int x, int y, int z)

void insert(int x, int y, int pos, int val)

};rope array;

int main()

return

0;

}

最後,就不帶模板的粘一下可持久化陣列的模板

由於struct內部有函式過載,有兩個版本。

struct rope   

int mid = (l + r) >> 1;

build(lc[k], l, mid);

build(rc[k], mid + 1, r);

} int query(int k, int l, int r, int

pos)

void insert(int

x, int &y, int l, int r, int

pos, int val)

int mid = (l + r) >> 1;

lc[y] = lc[x]; rc[y] = rc[x];

if (pos

<= mid)

insert(lc[x], lc[y], l, mid, pos, val);

else insert(rc[x], rc[y], mid + 1, r, pos, val);

} void build(int l, int r)

int find(int

x, int

y, int z)

void insert(int

x, int

y, int

pos, int val)

};

class rope   

int mid = (l + r) >> 1;

build(lc[k], l, mid);

build(rc[k], mid + 1, r);

} int query(int k, int l, int r, int

pos)

void insert(int

x, int &y, int l, int r, int

pos, int val)

int mid = (l + r) >> 1;

lc[y] = lc[x]; rc[y] = rc[x];

if (pos

<= mid)

insert(lc[x], lc[y], l, mid, pos, val);

else insert(rc[x], rc[y], mid + 1, r, pos, val);

} public:

void build(int l, int r)

int find(int

x, int

y, int z)

void insert(int

x, int

y, int

pos, int val)

};

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

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

可持久化陣列

日常不想放題目 luogu p3919 模板 可持久化陣列 題目中要求可以查詢歷史狀態,最暴力的想法是開 a m n 的二維陣列,每次修改暴力複製並修改,每次查詢暴力掃瞄,時間複雜度是 o m n 的,但這顯然是不行的.這個時候其實很容易想到線段樹,但線段樹維護的是當前狀態而無法維護歷史狀態,一種暴...

可持久化陣列

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