一切之始主席樹
可持久化並查集
//首先可持久化並查集我們是用主席樹來維護的,葉子節點維護每個位置的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 偶還是...