首页 > 其他分享 >并查集拓展

并查集拓展

时间:2023-03-16 22:12:58浏览次数:37  
标签:并查 复杂度 查集 拓展 这题 枚举 技能

上一期

由于上一期过水,只讲了一点点序列的问题,然而在乱逛看题解的时候,发现其实并查集能做到的远远不止图论与有限步骤序列问题,今天就从一(不会讲模板的)开始来记录一下并查集的美妙。


1.入门级别:P1196 [NOI2002] 银河英雄传说

这应该是最基础的运用,利用并查集来维护图的连通性,做一类合并问题。

这种题一般十分明显的需要用到并查集,大部分时候用并查集来辅助正解或来打暴力。

像这题……好像没什么好说的。(这题之前是蓝)

就正常维护就行了,真没什么好讲的。


2.入门进阶:P4616 [COCI2017-2018#5] Pictionary

只是留个练习题而已。

至于这题怎么做,把数小的作为父节点,然后用 \(\gcd\) 信息连成一棵树,在书上跑 \(lca\) 维护最大值就行了。

在连边的时候用并查集判断两边是否连上,如果已连上再链接由于边权更大不会更优,所以最终形态是棵树。

复杂度:\(O(n\log(n))\)。


3.一技能,化图为树:P3366 【模板】最小生成树(气氛逐渐中二起来)

这是利用定义去实现算法的第一种用法,把整张图拆开,再利用并查集去合并。

那么这题,没什么好说的吧……过。


4.一技能二段,spfa 附身(bushi):P4768 [NOI2018] 归程

这是这题的题解

通过并查集来维护生成树的 \(kruskal\) 算法,在对比 \(prime\) 就有了一点优势,其根本原因是并查集是整张图按照从小到大进行合并,所以在两点第一次连通时,他们的路径一定最小,就可以新建节点对原来两边的节点建边,点权为合并边时的边权,然后用这个新的点来代表整个连通图。

那么两点间的最小值明显就是 \(lca\) 的点权。

这道题就祥见另一个博客吧。


5.二技能,败者食尘:P3402 可持久化并查集

比较并查集是数据结构,特色还是得有。

这东西其实很好弄,只需要对操作建树,回退时在树节点上回退即可,这样复杂度是稳定 \(O(n)\) 的。但是不能进行路径压缩,所以合并并查集要用启发式合并,所以复杂度为 \(O(n\times \log(n))\)。

在线做法其实就跟可持久化数组一个概念,具体就不细讲了。

例题我是真没找些什么,所以一段技能就够了吧……


6.三技能,我是线段树???:P4145 上帝造题的七分钟 2 / 花神游历各国

这玩意是经典的线段树题目,应该学过线段树的都认识,但是为什么它有并查集标签呢。

这就是我在上个版本讲述的并查集处理序列问题。

这题我们可以先考虑一个暴力,那就是从 \(l\) 到 \(r\) 枚举 \(a_i\),然后对于每个数取 \(sqrt(n)\) 就行了。

我们可以发现,一个数其实取根号的次数特别少,所以在一定操作后,序列中会有很多 \(1\)。

那么这些 \(1\) 我们是不用修改的,直接跳过就行了。

那么现在问题就是,我们怎么跳过一段全部为 \(1\) 的区间。

我们就可以把所有为 \(1\) 的区间全部用并查集合并起来,记录并查集的右端点,发现枚举到一个数为 \(1\) 时,直接跳过去就可以了。


7.三技能二段,我是平衡树!!!:P5610 [Ynoi2013] 大学

首先这题和上面那个题有个很相像的地方,就是数被除很少次就会变成 \(1\),且枚举时有很多地方不用枚举。

那么就有一个暴力的思路,建 \(w\) (值域上限)个平衡树,对于每棵平衡树 \(i\),存储哪些数可以整除以 \(i\)。然后每次询问时暴力查找加修改即可。

这题与上题有个不同处,上一题你线段树可以卡过(然而其实是根本没卡),这题平衡树你就寄了。

上述复杂度: \(O(n\log(n)\log(w))\),明显没什么问题,但是过于毒瘤的时间限制让你无法发挥。

那么就只能想办法优化了,根据刚刚分析,有很多数其实是不用枚举的,所以我们对于每一个数建若干个并查集来存储当前因数有哪些数没被枚举,然后枚举时直接跳过这些数就行了,当要删除这个点时,直接合并并查集即可。

但是由于这题过于毒瘤,要卡常,慎写。

8.奥义:分块赐予我力量!!!:P3247 [HNOI2016]最小公倍数

题意简述:

给定一个无向图,边权带两个值 \((a,b)\),给定 \(q\) 次询问,每次询问给定两个点,求两个点直接是否有 \(\max(a)=x\) 且 \(\max(b)=y\) 的简单或非简单路径。

这种题可以想到一个暴力,把所有 \(\le x\) 且 \(\le y\) 的边加入,用并查集判断连通性并判断是否存在 \(=x\) 与 \(=y\) 的边即可。

但是对于多组询问,如果每次这么做,复杂度是承受不下的。

我们可以发现,其实每次询问不需要把所有并查集撤销完全,所以我们想一些巧妙的方法,可以让并查集撤回次数变少。

我们先睡个觉

标签:并查,复杂度,查集,拓展,这题,枚举,技能
From: https://www.cnblogs.com/gmtfff/p/17224362.html

相关文章

  • TZOJ 5784: 团伙 并查集
    描述 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足:1、我朋友的朋友是我的朋友;2、我敌人的敌人是我的朋友;所有是朋友的人组成一个团伙。告诉你关于......
  • ABC 293 ABCD(并查集)
    A-SwapOddandEven#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;typedefpair<LL,LL>PII;constLLMAXN=1e18,MINN=-1e18;constLLN=1e6......
  • 并查集一
    并查集一当我们需要快速判断两个元素是否归属于同一个集合或者将两个集合合并时,就会使用并查集 #include<iostream>usingnamespacestd;constintN=1e5+1......
  • [蓝桥杯 2019 省 A] 修改数组 ———并查集练习(大学复健)
    本题拿到第一反应桶排序思想似乎可以水过,但是很明显出问题了。#include<bits/stdc++.h>usingnamespacestd;intN;inlineintkd(){ intx=0,f=1;charch=getchar......
  • 蓝桥杯 & 青蛙过河(最快贪心) (不用并查集)
      点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=1000000+7;lla[N];llb[N];llc[N];lln,x;boolcheck(ll......
  • Java关于栈(Stack)、队列(Queue)知识点拓展
    Stack类:Stack继承了Vector,而Vector类底层使用数组存储数据,Stack对象中存储的数据也是存储在数组中,常用方法:push(Edata):把数据压入栈addElement():是父类Vect......
  • 并查集模板
    #include<bits/stdc++.h>usingnamespacestd;intfa[10005];intm,n;intfind(intx){ if(fa[x]!=x){ fa[x]=find(fa[x]); } returnfa[x];}booljudge(intx,......
  • 【并查集】LeetCode 990. 等式方程的可满足性
    题目链接990.等式方程的可满足性思路并查集模板题,模板可以参考常用算法模板。将字母视为结点,==表示有路径,!=表示无路径。遍历x==y,建立图前驱关系遍历x!=y,......
  • 信号与系统(拓展二):无限集
    无限集分为可数无限集和不可数无限集。可数集例如:自然数集、有理数集、证书集;不可数集例如:实数集。无限集比大小方法:如果两个无限集A、B的元素之间存在一一对应关系,则认为......
  • 信号与系统(拓展一):勒贝格积分
    1.勒贝格关于函数相等的定义如何定义两个函数f1(t)和f2(t)相等(即何时f1(t)=f2(t))?我们在高中所学的定义是这样的:f1(t)和f2(t)定义域相同,且对于定义域上任意的t0,有f1(t0)......