BZOJ 3673: 可持久化并查集(可持久化并查集+启发式合并)
http://www.lydsy.com/JudgeOnline/problem.php?id=3673
思路:
可持久化数组可以用可持久化线段树来实现,并查集的查询操作和原来的一般并查集操作是差不多的,只不过是在线段树上操作。需要注意的是并查集的合并,需要按秩来进行启发式合并。
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = *+; int n,m,tot;
int t[maxn*],h[maxn*]; struct node
{
int l,r,fa;
}a[maxn*]; int build(int l, int r)
{
int root = ++tot;
if(l==r) {a[root].fa = l;return root;}
int mid = (l+r)>>;
a[root].l = build(l,mid);
a[root].r = build(mid+,r);
return root;
} int query(int root, int x, int l, int r)
{
if(l==r) return root;
int mid = (l+r)>>;
if(x<=mid) return query(a[root].l,x,l,mid);
else return query(a[root].r,x,mid+,r);
} int finds(int root, int x)
{
int p = query(root,x,,n);
if(x == a[p].fa) return p;
else return finds(root,a[p].fa);
} int modify(int pre, int x, int y, int l, int r)
{
int root = ++tot;
if(l==r)
{
a[root].fa = y;
h[root] = h[pre]; //这个不能忘
return root;
}
a[root].l = a[pre].l, a[root].r = a[pre].r;
int mid = (l+r)>>;
if(x<=mid) a[root].l = modify(a[pre].l, x, y, l, mid);
else a[root].r = modify(a[pre].r, x, y, mid+, r);
return root;
} void update(int root, int x, int l, int r)
{
if(l==r) {h[root]++;return;}
int mid = (l+r)>>;
if(x<=mid) update(a[root].l,x, l, mid);
else update(a[root].r,x, mid+, r);
} void unions(int x, int y, int i)
{
if(h[x]>h[y]) swap(x,y);
t[i] = modify(t[i-],a[x].fa,a[y].fa,,n); //因为上面的交换,所以这里用fa
if(h[x]==h[y]) update(t[i],a[y].fa,,n); //如果深度相等,则插入后深度会+1
} int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
tot = ;
t[] = build(,n);
for(int i=;i<=m;i++)
{
int op;
scanf("%d",&op);
if(op==)
{
int aa,bb;
scanf("%d%d",&aa,&bb);
t[i] = t[i-];
int x = finds(t[i],aa);
int y = finds(t[i],bb);
if(a[x].fa != a[y].fa) unions(x,y,i);
}
if(op==)
{
int aa;
scanf("%d",&aa);
t[i] = t[aa];
}
if(op==)
{
int aa,bb;
scanf("%d%d",&aa,&bb);
t[i] = t[i-];
int x = finds(t[i],aa);
int y = finds(t[i],bb);
if(a[x].fa == a[y].fa) puts("");
else puts("");
}
}
return ;
}
BZOJ 3673: 可持久化并查集(可持久化并查集+启发式合并)的更多相关文章
- 并查集+优先队列+启发式合并 || 罗马游戏 || BZOJ 1455 || Luogu p2713
题面:P2713 罗马游戏 题解: 超级大水题啊,特别水.. 并查集维护每个人在哪个团里,优先队列维护每个团最低分和最低分是哪位,然后每次判断一下哪些人死了,随便写写就行 并查集在Merge时可以用启 ...
- bzoj 3673&3674 可持久化并查集&加强版(可持久化线段树+启发式合并)
CCZ在2015年8月25日也就是初三暑假要结束的时候就已经能切这种题了%%% 学习了另一种启发式合并的方法,按秩合并,也就是按树的深度合并,实际上是和按树的大小一个道理,但是感觉(至少在这题上)更好 ...
- Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Description n个集合 m个操作 操作: 1 a b 合并a,b所在集 ...
- BZOJ.3673/3674.可持久化并查集(可持久化线段树 按秩合并/启发式合并)
BZOJ 3673 BZOJ 3674(加强版) 如果每次操作最多只修改一个点的fa[],那么我们可以借助可持久化线段树来O(logn)做到.如果不考虑找fa[]的过程,时空复杂度都是O(logn). ...
- bzoj 3674: 可持久化并查集加强版 (启发式合并+主席树)
Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… ...
- [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)
[BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...
- 并查集+启发式合并+LCA思想 || 冷战 || BZOJ 4668
题面:bzoj炸了,以后再补发 题解: 并查集,然后对于每个点记录它与父亲节点联通的时刻 tim ,答案显然是 u 到 v 的路径上最大的 tim 值.启发式合并,把 size 小的子树往大的上并,可 ...
- [BZOJ 4668]冷战(带边权并查集+启发式合并)
[BZOJ 4668]冷战(并查集+启发式合并) 题面 一开始有n个点,动态加边,同时查询u,v最早什么时候联通.强制在线 分析 用并查集维护连通性,每个点x还要另外记录tim[x],表示x什么时间与 ...
- [BZOJ 4025]二分图(线段树分治+带边权并查集)
[BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...
随机推荐
- 20165305 苏振龙《Java程序设计》第九周学习总结
第十三章 Java网络编程 学习了解用于网络编程的类,了解URL.Socket.InetAddress和DatagramSocket类在网络编程中的重要作用 使用URL创建对象的应用程序称作客户端程序 ...
- Music life
some songs: you are you are <<你眼中的世界> Trouble I'm In > 1:40 secs 忧桑钢琴曲 < 豆花之歌 The Tru ...
- 如何使用Linux 命令more 查看文本文件
Linux 下有很多实用工具可以让你在终端界面查看文本文件.其中一个就是 more. more 跟我之前另一篇文章里写到的工具 —— less 很相似.它们之间的主要不同点在于 more 只允许你向前 ...
- corn
http://www.cnblogs.com/itech/archive/2011/02/09/1950226.html service crond start ---查看crontab服务是否启动 ...
- mysql 通过查看mysql 配置参数、状态来优化你的mysql
我把MYISAM改成了INNODB,数据库对CPU方面的占用变小很多' mysql的监控方法大致分为两类: 1.连接到mysql数据库内部,使用show status,show variables,f ...
- JavaScript 条件判断算法综合实战
在赌场21点游戏中,玩家可以通过计算牌桌上已经发放的卡牌的高低值来让自己在游戏中保持优势,这就叫21点算法. 根据下面的表格,每张卡牌都分配了一个值.如果卡牌的值大于0,那么玩家应该追加赌注.反之,追 ...
- jquery获取包含本身的元素
我们知道,使用jquery获取一个元素内的所有元素非常容易,使用jQuery.html()就可以. 如果是js语法的话,使用domObj.innerHTML也很容易实现. 那么问题来了,要想获取包涵节 ...
- ThirdAPI
//public class ThirdAPI //{ // [DllImport("ThirdAPI.dll")] // public static extern int Ini ...
- Python学习基础(三)——装饰器,列表生成器,斐波那契数列
装饰器——闭包 # 装饰器 闭包 ''' 如果一个内部函数对外部(非全局)的变量进行了引用,那么内部函数被认为是闭包 闭包 = 函数块 + 定义时的函数环境 ''' def f(): x = 100 ...
- Oracle Redo log 状态及工作原理解析
Oracle重做日志(redo log)是用来记录操作条目,用于数据库数据恢复.为了提高效率,oracle通常建议设置三组redo log.本文将对重做日志组的状态以及多种状态之间切换做解析,力求掌握 ...