可持久化并查集
简单来说就是两颗主席树
一颗维护 父亲节点是谁
一颗维护 深度
为什么要维护深度?
降低时间复杂度
并查集如果不优化的查询的话是这样:
int findx(int x)
{
return x == fa[x]?x : findx(fa[x]);
}
void hebing(int x,int y)
{
int xx = findx(x);
int yy = findx(y);
if(xx != yy)
{
fa[xx] = yy;
}
}
这个时间复杂度最坏可以到达O(n) 的
优化一:
路径压缩是这样:
基本是常数复杂度?
void hebing(int x,int y)
{
int xx = findx(x);
int yy = findx(y);
if(xx != yy)
{
fa[xx] = yy;
}
}
int findx(int x)
{
return x == fa[x]?x : fa[x] = findx(fa[x]);
}
但是可持久化的话这样每压缩一次就算一个状态? 可能会MLE?
优化二:
按秩合并:
就是按照他的这个树的大小来合并,把小的树的根节点连到大的树的根节点上面这样可以使树尽量低 查询的复杂度是logn
代码是这样:
int findx(int x)
{
return x == fa[x]?x :findx(fa[x]);
}
void hebing(int x,int y)
{
int xx = findx(x);
int yy = findx(y);
if(xx != yy)
{
int dx = dep[xx];
int dy = dep[yy]