首页 > 其他分享 >【模板】并查集 DSU

【模板】并查集 DSU

时间:2022-11-06 19:25:24浏览次数:97  
标签:查集 struct int 染色 tt DSU fa find 模板

posted on 2021-09-12 15:49:52 | under 模板 | source

0x00 模板

并查集维护的是这样一个问题:

\(n\) 个点,初始时每个点自己一个集合。

  • \({\tt merge}(x,y)\):合并 \(x,y\) 所在集合。
  • \({\tt query}(x,y)\):询问 \(x,y\) 是否在同一个集合中。

把每个集合看作一棵有根树,记 \(fa_x\) 为 \(x\) 的父亲,添加操作 \({\tt find}(x)\) 为沿着 \(fa\) 往上爬到达的根结点。

对于 \(\tt merge\) 操作,找到 \(fx={\tt find}(x),fy={\tt find(y)}\),把这两棵有根树合并,直接把 \(fx\) 连向 \(fy\) 做 \(fy\) 的儿子,反过来也行。

对于 \(\tt query\) 操作,如果 \({\tt find}(x)={\tt find}(y)\),说明 \(x,y\) 所在有根树的根相同,即在同一棵有根树中,即在同一集合中。

写下来会发现 TLE,我们需要一些优化,两个角度:

  • \({\tt find}(x)\) 时,如果这棵树变成一条链,我一直在跳链,有意义吗?可以用类似于记忆化的技巧,把链打成菊花,一步到位。
  • \({\tt merge}(x)\) 时,如果我执着地把大树连到小树上,这不就成链了吗?考虑把小树连到大树上,发现每次跳 \(fa\) 子树大小至少翻倍(反证法),那么树高就是 \(O(\log n)\) 了。

Tarjan 告诉我们,第一种叫路径压缩,\(O(n\log n)\);第二种叫启发式合并,\(O(n\log n)\);如果两种一起用,复杂度降至 \(O(n\alpha(n))\),其中 \(\alpha(n)\) 为反阿克曼函数,增长极慢,在 \(10^9\) 范围内可看作 \(4\)。于是我们有了一个优秀的并查集。

template<int N> struct dsu{
    int fa[N+10],siz[N+10],cnt;
    dsu(int n=N):cnt(n){for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;}
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    void merge(int x,int y){if(x=find(x),y=find(y),x!=y) siz[x]<siz[y]&&(swap(x,y),0),cnt--,fa[y]=x,siz[x]+=siz[y];}
};

0x01 区间染色

\(n\) 个点排成一列,一开始没被染色,支持操作:

  • \({\tt assign}(l,r,k)\):将 \([l,r]\) 的点染色成 \(k\),已被染色的点忽略
  • \({\tt remain}(l,r)\):询问 \([l,r]\) 内有没有未被染色的点。

修改 \(fa_x\) 的定义:\(x\) 右边(包括 \(x\))第一个未被染色的点。显然初始时 \(fa_x=x\)。

考虑 \(\tt assign\) 操作,我们先找到 \({\tt find}(l)=l'\) 这个点没被染色,如果 \(l'\leq r\),记录 \(c_{l'}=k\) 我们把 \(l'\) 染成了 \(k\),根据定义我们应该修改 \(fa_{l'}\) 了,将它指向下一个未被染色的点,显然这个点是 \({\tt find}(l'+1)\),然后迭代更新即可。

考虑 \(\tt remain\) 操作,定义,若 \({\tt find}(l)\leq r\) 就有剩下的点。

我们发现这些操作很像并查集的操作,可以直接套用,路径压缩也可以加,注意最好不要启发式合并,以免打乱顺序。

template<int N> struct exdsu:public dsu<N>{//展开
    int a[N+10];
    exdsu(){memset(a,0,sizeof a);}
    void assign(int l,int r,int k){while(l<=r) if(this->find(l)==l) a[l]=k,this->fa[l]=this->find(l+1); else l=this->find(l);}
    bool remain(int l,int r){return this->find(l)<=r;}
    int operator[](int i){return a[i];}
};
template<int N> struct exdsu:public dsu<N>{
    int a[N+10];
    exdsu(){memset(a,0,sizeof a);}
    void assign(int l,int r,int k){while((l=this->find(l))<=r) a[l]=k,this->merge(l,l+1);}
    bool remain(int l,int r){return this->find(l)<=r;}
    int operator[](int i){return a[i];}
};

继承

面向对象语言的特性,以 C++ 为例,格式为:

struct a{};
struct b:public a{};

在 C++ 中,structclass 几乎相同,区别在于 struct 默认 publicclass 默认 private,不过这不重要。

在 OI 中使用对象继承,可以把父类的变量、函数移植到新的子类,子类也有这些函数,可以在子类创建新的变量和函数。构造函数还要自己写,父子的都会调用。

为了过编译,父类的函数需要加 this->merge(x,y),告诉编译器 merge 是父类的函数。OI 用到的继承可以到这停了。

话说整一下复杂度,\(O(n\log n)\),每个点只染色一次,合并只有 \(O(n)\) 次,均摊 \(O(n)\),\(\log\) 是并查集复杂度。

0x02 静态区间覆盖

\(n\) 个点排成一列,一开始没被染色,支持操作:

  • \({\tt assign}(l,r,k)\):将 \([l,r]\) 的点染色成 \(k\),已被染色的点颜色被覆盖

最后输出 \(n\) 个点的颜色。

每个点的颜色由它最后被染的颜色决定,倒着做上一题的覆盖操作就好了。

标签:查集,struct,int,染色,tt,DSU,fa,find,模板
From: https://www.cnblogs.com/caijianhong/p/16863433.html

相关文章

  • 【模板】Z 函数(扩展 KMP)
    postedon2022-08-0823:29:53|under模板|source#include<cstdio>#include<cstring>#include<algorithm>usingnamespacestd;typedeflonglongLL;intn,......
  • 【模板】Tarjan
    postedon2022-07-0720:52:49|under模板|source0x00有向图缩点现有一有向图\(G=(V,E)\),称一个点集\(E'\inE\)为强连通分量,当且仅当\(E'\)的任意两点可以互......
  • 【模板】ST 表 Sparse Table
    postedon2022-07-2219:15:58|under模板|sourcetemplate<intN,classT=int,intlogN=20>structSTable{ inttot,lg[N+10];Tf[logN+1][N+10]; STable():tot(0......
  • 【模板】Splay
    postedon2022-07-2117:03:54|under模板|source(介绍等会补)调试:getpre、getsuf、find手写,常数不要乘以二。UB:getkth和getrnk叠起来的时候root会改!UB:getp......
  • 【模板】popcount
    postedon2022-02-0418:11:33|under模板|sourceintpopcount(intx){#defineBIT2(n)n,n+1,n+1,n+2#defineBIT4(n)BIT2(n),BIT2(n+1),BIT2(n+1),BIT2......
  • 【模板】Bellman-Ford 判负环
    postedon2022-08-1018:07:25|under模板|source0x00Bellman-Ford最短路经过的边数不超过\(n-1\),因此若松弛轮数达到\(n\)轮即有负环。复杂度\(O(nm)\)。int......
  • 【模板】AC 自动机
    postedon2022-06-1111:17:10|under模板|sourcetemplate<intN,intM=26,intD='a'>structacam{ intch[N+10][M],cnt[N+10],tot,fail[N+10]; intsum[N+10],i......
  • 【模板】01-trie
    postedon2022-01-1716:13:39|under模板|source#include<cstdio>#include<cstring>#include<algorithm>usingnamespacestd;template<intN,intM=2,intM......
  • webstorm里面react快速创建模板
    webstorm里面react快速创建模板rcc+tab键--用ES6模块系统创建一个React组件类rccp+tab键--创建一个带有PropTypes和ES6模块系统的React组件类rcfc+tab键-......
  • 高仿英雄联盟游戏网页制作作业 英雄联盟LOL游戏HTML网页设计模板 简单学生网页设计 静
    ......