可持久化專題

2021-10-10 18:13:42 字數 3130 閱讀 1095

一切之始主席樹

可持久化並查集

//首先可持久化並查集我們是用主席樹來維護的,葉子節點維護每個位置的fa 

//維護2個量:每個點的父親和每棵樹的根節點的高度。

//那麼不使用路徑壓縮的話這個版本的主席樹和上個版本的主席樹

//有且只有乙個點會被改動。

//那麼就可以進行可持久化了。

//既然取消了路徑壓縮,為了保證複雜度,我們需要進行按秩合併。

//按秩合併其實就是,我們以樹高為秩,每次將樹高低的樹合併到樹高高的樹上,

//那麼對於樹高高的樹來說樹高並沒有變(也就說原樹訪問根節點的代價並沒有變),而樹高低的樹訪問根節點的代價只增加了\text1(這棵樹的根節點變成了樹高高的樹的兒子)。

//還有一種特殊情況那就是兩棵樹樹高相同。

//這個時候把樹a合併到樹b上b的樹高會增加1,而

//樹a的高度則不會改變。

//rta,rtb其實是a點和b點在主席樹里的編號,depth指的是樹高

#include const int n = 1e5 + 10;

int n, m, i, j, k, cntu;

int fa[n << 7], depth[n << 7], root[n << 1], lc[n << 7], rc[n << 7];

int build(int l, int r)

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

lc[u] = build(l, mid);

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

return u;

}int query(int u, int l, int r, int x)

int update(int pre, int x, int y, int l, int r)

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

if (x <= mid) lc[u] = update(lc[pre], x, y, l, mid);

else rc[u] = update(rc[pre], x, y, mid + 1, r);

return u;

}void add(int u, int l, int r, int x)

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

if (x <= mid) add(lc[u], l, mid, x);

else add(rc[u], mid + 1, r, x);

}int find(int v, int x)

int main() else if (op == 2) scanf("%d", &v), root[i] = root[v];

else

} return 0;

}

可持久化字典樹區間

#include #include #include #include #include #include #include #define ll long long

using namespace std;

int cnt[1000010*31],c[1000010*31][2],tot,root[1000010];

int clone()

void insert(int last,int &now,int x)//類似主席樹的思想

//cnt[tmp]=cnt[last]+1;

}int query(int l,int r,int x)

else

}}

樹上可持久化字典樹

//其實樹上 可持久化 trie  和樹上主席樹類似,

//就是當前節點呼叫的 las 節點變成了該節點的父節點,

//查詢的時候也是和樹上主席樹類似的套路,

#include#include#include#include#include#define clr(a,b) memset(a,b,sizeof(a))

#define lson lr<<1,l,mid

#define rson lr<<1|1,mid+1,r

#define key_value ch[ch[root][1]][0]

#pragma comment(linker, "/stack:102400000000,102400000000")

typedef long long ll;

const ll mod = 1000000007;

const int n = 1e5+15;

const int maxn = 1e6+15;

const int letter = 130;

const int inf = 1e9;

const double pi=acos(-1.0);

const double eps=1e-10;

using namespace std;

inline int read()

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

return x*f;

}int n,q,head[n],tot,a[n];

int fa[n][18],deep[n],bin[18];

int ch[n*18][2],sum[n*18],root[n],cnt;

struct edgese[n<<1];

void addedges(int u,int v)

int trie_insert(int x,int val)

sum[y]=sum[x]+1;

return tmp;

}int trie_query(int x,int y,int z,int val)

void init()

int main()

fa[1][0]=0;

dfs(1,0);

for(int j=1;j<=16;j++)

for(int i=1;i<=n;i++)

fa[i][j]=fa[fa[i][j-1]][j-1];

while(q--)

}return 0;

}

可持久化專題(二) 可持久化陣列的實現

前言 呃,首先宣告,看這篇部落格前,最好先去學一學主席樹,畢竟可持久化陣列的實現是完全基於主席樹的 那些亂七八糟的玄學演算法請走開 l in klink link 主席樹詳見部落格可持久化專題 一 主席樹 可持久化線段樹 順便吐槽一句,可持久化陣列這個名字聽起來真的很智障。簡介 可持久化陣列支援單點...

可持久化專題(三) 可持久化並查集

前言 要學可持久化並查集,必須先會可持久化陣列。l in klink link 可持久化陣列詳見部落格可持久化專題 二 可持久化陣列的實現 簡介 可持久化並查集應該是乙個挺實用的資料結構 例如noi2018day1t1中就有它的身影 它主要建立於可持久化陣列的基礎之上 而可持久化陣列的實現是完全基於...

可持久化線段樹 專題 AbandonZHANG

可持久化線段樹 函式式線段樹 可持久化資料結構 persistent data structure 就是利用函式式程式設計的思想使其支援詢問歷史版本 同時充分利用它們之間的共同資料來減少時間和空間消耗。所以這裡講的可持久化線段樹也叫函式式線段樹 又叫主席樹 因為先驅就是fotile主席orz 偶還是...