题目链接:https://www.luogu.org/problemnew/show/P3402
解题思路:
可持久化并查集也就是可持续化线段树 + 并查集 == 主席树 + 并查集
像我们平常做的并查集都是路径压缩,但因为要保证可持续化,所以信息不能改变,所以我们采用启发式合并来合并集合。
启发式合并的树最高深度不会超过log(n)+1。因为深度为2的树需要两个点,那么深度为3的需要两个深度为2的也就是2*2==4个点。所以2^n次方个点最深可以到log(n)+1。
所以主席树每个点就需要维护他的父亲和它为根的树的深度。而且只需要维护区间为1的节点就可以了。
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define lson l,mid,s[rt].ls
#define rson mid+1,r,s[rt].rs
using namespace std;
typedef long long ll;
const int mx = 2e5 + 10;
const int mod = 1e9+7;
const ll INF = -1e16;
int n,m,siz,root[mx];
struct node
{
int f,dep;
int ls,rs;
}s[mx*30];
void build(int l,int r,int& rt)
{
rt = siz++;
if(l==r){
s[rt].f = l;
return ;
}
int mid = (l+r)&g