标签:访问 不能 均衡 强制 题意 双向链表 本质 长度 超过
每次将秩小的合并到秩大的,若相同,秩加 1 。
秩反应的是容纳水平, 秩越高, 容纳水平越高, 这样才能更加均衡地填满.
每次只修改 $O(1)$ 的元素,可以快速撤销。
HDU 5354
分治 + 按秩合并并查集,判断删去任意一条边后,该图是否是二分图。
给序列,每次访问一个区间,若某点被访问过,则不访问这个点。
类似地,给树,每次访问一条儿子 - 祖先路径,若某点被访问过,则不访问这个点。
本质:给每个点有且仅有一个后继的结构,每次访问某一段,若某点被访问过,则不访问这个点。
用并查集进行路径压缩,均摊线性。
变:给树,每次访问某条路径,若某点被访问过,则不再访问。
路径由两条儿子 - 祖先路径组成。
经典模型:若干次区间赋值,每次将区间 [l, r] 赋值 w ,一个点最终的值为区间的值的最小值,求每个点最终的值。
通过排序,路径压缩。
优点:性价比高——跑得快、短。
只支持删除的双向链表,本质路径压缩.
BZOJ 3211
区间开方, 区间求和.
开方次数很小,暴力枚举区间 [l, r] 每个不等于 1 的位置开方,使用双向链表对这个结构进行维护。
对查询,再维护树状数组。
’‘
「BZOJ 1854」「SCOI 2010」 游戏
给 n(<= 100000) 对 {a, b} , 每对中选择一个, 求从 1 开始的最长值域连续段的长度.
对值域建图。
把每个值当作图中的一个点.
对于点对 {a, b} , 将点 a 与点 b 进行连边.
每条边可以配对一个点, 求最大的 x , 满足前 x 个点可以被不同的边进行配对.
考虑一个连通块.
如果这个连通块是一棵树, 那么可以对任意的 n-1 个点进行配对, 由于我们求从 1 开始的最长值域连续段, 所以对前 n-1 小的点进行配对, 最大的点不能被配对.
如果这个连通块至少有一个环, 那么所有点都可以进行配对.
我们只需要找到某个点 id , 它所在的连通块是一棵树, 且 id 是这个连通块中最大的点, 那么答案为 id-1 .
「SCOI2016」 萌萌哒
求有多少个无前导零的 $N(N\le 10^5)$ 位数 $A$ , 满足 $M(M\le 10^5)$ 个限制条件 $L~R~X~Y$ : $A[L+i] = A[X+i]$ .
对 ST 表用并查集, 标记下传.
「BZOJ 3376」 方块游戏
题意
给定 30000 个方块, q 次操作:
M x y: 将标号为 x 的方块所在的堆, 叠到标号为 y 的方块所在的堆之上.
C x: 求标号为 x 的方块下有多少个方块.
分析
带权并查集.
两个在同一堆的方块在一个并查集内, f[x] 在 x 下.
维护 f[x]: x 在并查集的父亲.
s[x]: x 为代表元素, 集合的大小.
w[x]: x 与父亲之间有多少个方块.
「BZOJ 2303」「APOI 2011」方格染色
题意
在 n * m 的方格中, 每个格子要填上 0 或 1, 且满足任意一个四方格中, 有 1 个 1 或者 3 个 1 .
已知某些格子中填的数, 求有多少种合法的填法.
n, m <= 10 ^ 6 .
分析
探究合法填法的一些性质.
a[x, y] = a[x-1, y-1] ^ a[x, y-1] ^ a[x-1, y] ^ 1 .
将 a[2 ~ x][2 ~ y] 异或起来, 可以得到 a[x, y] = a[1, 1] ^ a[x, 1] ^ a[1, y] ^ [(n-1) * (m-1) 为奇数] .
假如我们能够确定第一行, 第一列, 那么所有的格子都确定了.
枚举 a[1, 1] 的取值, 那么限制条件变为二元的限制条件 a[x, 1] ^ a[1, y] = c .
我们将 (x, 1) 与 (1, y) 的关系通过并查集维护, 最后查询 2 ^ {连通块个数 - 1} .
「BZOJ 1202」狡猾的商人
f[x] < x .
维护 b[x] = sum(f[x], f[x]+1, ..., x) .
给 n 点, m 带权边的无向图,在线求在所有边权不超过 d 的边的作用下,某个点或某两个点的连通性信息。
例子:可持久化并查集。n 个点, 支持连边, 和查询在前 t 次操作下, 某两个点是否连通。这个例子隐藏起了时间这一维,将时间量化就可以完成转化: 在时刻 t 将某两个点连边, 就相当于 x 与 y 之间存在一条边, 边权为 t .
将边权从小到大进行排序, 不断加边, 用并查集进行维护.
将并查集的功能拓展, 支持维护历史信息.
按秩合并.
多记录一个 w 数组, 在并查集中, 当点 x 的父亲指向点 y 的时候, 记录 w[x] = 边权 .
在查找一个节点 x 在不超过 d 的边权的作用下的并查集时, 只需要将 x 在并查集中从下往上跳, 直到恰好跳到满足 w[x] > d 时停止, 就能找到集合的代表元素.
如果需要查询连通块内的信息, 进行可持久化线段树合并, 对每个点开一个 map 来记录所有的根.
Kruskal 重构树。
每次合并的时候, 新建点 cur , 将两个代表元素的父亲指向当前这个新建点 cur .
找 x 在不超过 d 的边权的作用下的代表元素时, 不能直接往上跳, 改用树上倍增.
如果需要查询连通块内的信息, 可以进行可持久化线段树合并, 这时候每个点对应的根唯一, 不再需要开 map . 或者可以将 Kruskal 重构树进行 dfs 序剖分, 转化为序列的问题.
比较一下两种写法的优缺点:
自己的写法速度较快, 查询代表元素可以直接查询, 不支持 dfs 序剖分, 需要开 map .
Kruskal重构树速度较慢, 查询代表元素需要树上倍增, 支持 dfs 序剖分, 不需要开 map .
「BZOJ 3551」 Peaks
「BZOJ 4668」冷战
题意
两种操作:
0 x y 将 x 和 y 进行连边.
1 x y 询问 x 和 y 在什么时候刚刚连通.
n, m <= 500000, 强制在线.
分析
按秩合并.
维护信息 w[x] 表示 x 合并到 f[x] 的时间.
对于查询暴力找 LCA , 并求路径的 w[x] 的最大值 (其实必然是最上面的两个点中的一个) .
离线算法, 用于求出若干组点 (x, y) 的 LCA , 效率极高.
先将所有询问读入, 然后对树进行 DFS . 回溯的过程中将 f[son] 赋为 cur ; 访问完一个节点时进行查询, 对于 (cur, x) , 若 x 已被访问, 那么查询 x 在并查集中的祖先.
标签:访问 不能 均衡 强制 题意 双向链表 本质 长度 超过
原文地址:http://www.cnblogs.com/Sdchr/p/7614530.html