BZOJ3673/3674:可持久化并查集
Description
n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
0<n,m<=2*10^4
Input
Output
Sample Input
1 1 2
3 1 2
2 0
3 1 2
2 1
3 1 2
Sample Output
1
0
1
Solution
板子题……只不过网上有很多假做法。
具体做法就是整两个可持久化数组(不知道谁起的这么鬼畜的名字……我还是更喜欢叫他可持久化线段树)来记录并查集的$fa$数组和$dep$数组。因为路径压缩会破坏可持久化的结构,所以我们只能记录$dep$数组来按秩合并。
网上很多只搞了一颗可持久化线段树,维护$fa$就可持久化线段树$insert$一条链,维护$dep$就修改历史版本上的点的做法是错的……已经被卡掉了QAQ
Code
#include<iostream>
#include<cstdio>
#define N (200009)
using namespace std; int n,m,lastans,opt,x,y; struct Tree
{
struct Sgt{int ls,rs,v;}Segt[N*];
int sgt_num,a[N],Root[N];
int Build(int l,int r)
{
int now=++sgt_num;
if (l==r) {Segt[now].v=a[l]; return now;}
int mid=(l+r)>>;
Segt[now].ls=Build(l,mid);
Segt[now].rs=Build(mid+,r);
return now;
}
int Update(int pre,int l,int r,int x,int v)
{
int now=++sgt_num;
Segt[now].ls=Segt[pre].ls;
Segt[now].rs=Segt[pre].rs;
if (l==r) {Segt[now].v=v; return now;}
int mid=(l+r)>>;
if (x<=mid) Segt[now].ls=Update(Segt[now].ls,l,mid,x,v);
else Segt[now].rs=Update(Segt[now].rs,mid+,r,x,v);
return now;
}
int Query(int now,int l,int r,int x)
{
if (l==r) return Segt[now].v;
int mid=(l+r)>>;
if (x<=mid) return Query(Segt[now].ls,l,mid,x);
else return Query(Segt[now].rs,mid+,r,x);
}
}CT[]; int Find(int x,int t)
{
int fa=CT[].Query(CT[].Root[t],,n,x);
return x==fa?x:Find(fa,t);
} int main()
{
scanf("%d%d",&n,&m);
for (int i=; i<=n; ++i)
CT[].a[i]=i, CT[].a[i]=;
CT[].Root[]=CT[].Build(,n);
CT[].Root[]=CT[].Build(,n);
for (int i=; i<=m; ++i)
{
scanf("%d",&opt);
if (opt==)
{
CT[].Root[i]=CT[].Root[i-];
CT[].Root[i]=CT[].Root[i-];
scanf("%d%d",&x,&y);
/*x^=lastans; y^=lastans;*/
int fx=Find(x,i),fy=Find(y,i);
if (fx==fy) continue;
int dfx=CT[].Query(CT[].Root[i],,n,fx);
int dfy=CT[].Query(CT[].Root[i],,n,fy);
if (dfx>dfy) swap(fx,fy);
CT[].Root[i]=CT[].Update(CT[].Root[i],,n,fx,fy);
if (dfx!=dfy) continue;
CT[].Root[i]=CT[].Update(CT[].Root[i],,n,fy,dfy+);
}
if (opt==)
{
scanf("%d",&x); /*x^=lastans;*/
CT[].Root[i]=CT[].Root[x];
CT[].Root[i]=CT[].Root[x];
}
if (opt==)
{
CT[].Root[i]=CT[].Root[i-];
CT[].Root[i]=CT[].Root[i-];
scanf("%d%d",&x,&y);
/*x^=lastans; y^=lastans;*/
int fx=Find(x,i),fy=Find(y,i);
if (fx==fy) puts("")/*, lastans=1*/;
else puts("")/*, lastans=0*/;
}
}
}
BZOJ3673/3674:可持久化并查集的更多相关文章
- [BZOJ3673&3674]可持久化并查集&加强版
题目大意:让你实现一个可持久化的并查集(3674强制在线). 解题思路:刚刚介绍了一个叫rope的神器:我是刘邦,在这两题(实际上两题没什么区别)就派上用场了. 正解应该是主席树||可持久化平衡树,然 ...
- [bzoj3673/3674可持久化并查集加强版]
n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n,m<=2 ...
- BZOJ 3674 可持久化并查集加强版(路径压缩版本)
/* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...
- BZOJ 3674 可持久化并查集加强版(按秩合并版本)
/* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...
- 【BZOJ】3673: 可持久化并查集 by zky & 3674: 可持久化并查集加强版(可持久化线段树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3674 http://www.lydsy.com/JudgeOnline/problem.php?id ...
- bzoj 3673&3674 可持久化并查集&加强版(可持久化线段树+启发式合并)
CCZ在2015年8月25日也就是初三暑假要结束的时候就已经能切这种题了%%% 学习了另一种启发式合并的方法,按秩合并,也就是按树的深度合并,实际上是和按树的大小一个道理,但是感觉(至少在这题上)更好 ...
- BZOJ 3674 可持久化并查集加强版(主席树变形)
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Submit: 2515 Solved: 1107 [Submit][Sta ...
- bzoj 3674: 可持久化并查集加强版 (启发式合并+主席树)
Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… ...
- [bzoj] 3673 3674 可持久化并查集 || 可持久化数组
原题 加强版 题意: 可持久化并查集模板-- 题解: 用可持久化线段树维护一个可持久化数组,来记录每一次操作后的状态. 不能用路径压缩,但是要按置合并,使复杂度保证在O(log) #include&l ...
随机推荐
- CSS 样式属性
大小 width 宽 body { min-width:1200px; height 高 } ...
- 【模板】堆优化 + dij +pair 存储
就是短 感谢Cptraserdalao的博客 #include<bits/stdc++.h> using namespace std; struct node { int val,num; ...
- 撩课-Web大前端每天5道面试题-Day28
1.用setTimeout()方法来模拟setInterval()与setInterval()之间的什么区别? 首先来看setInterval的缺陷,使用setInterval()创建的定时器确保了定 ...
- Improving the GPA(hdu4968)dfs
Improving the GPA Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- Maven 那些破事
deploy 只上传了pom 晚上输命令,打算打包上传到本地库里,然后去服务器上部署新版本 mvn clean package deploy 结果看着mvn的build过程只是上传了pom,去库服务器 ...
- BZOJ2337: [HNOI2011]XOR和路径(期望 高斯消元)
题意 题目链接 Sol 期望的线性性对xor运算是不成立的,但是我们可以每位分开算 设\(f[i]\)表示从\(i\)到\(n\)边权为1的概率,统计答案的时候乘一下权值 转移方程为 \[f[i] = ...
- [WPF 基础知识系列] —— 绑定中的数据校验Vaildation
前言: 只要是有表单存在,那么就有可能有对数据的校验需求.如:判断是否为整数.判断电子邮件格式等等. WPF采用一种全新的方式 - Binding,来实现前台显示与后台数据进行交互,当然数据校验方式也 ...
- 基于纤程(Fiber)实现C++异步编程库(一):原理及示例
纤程(Fiber)和协程(coroutine)是差不多的概念,也叫做用户级线程或者轻线程之类的.Windows系统提供了一组API用户创建和使用纤程,本文中的库就是基于这组API实现的,所以无法跨平台 ...
- Java:运算符的问题
算术运算符: 算术运算符的注意问题 1. 如果对负数取模,可以把模数负号忽略不记,如:5%-2=1.但被模数是负数就另当别论. -5%3=-2:-5%-3=-2:符号跟被模数(左边). 2. 对于除号 ...
- SQL语句创建数据库及表
--删除数据库drop database ArchiveDev; --建立归档数据库CREATE DATABASE ArchiveDev; USE ArchiveDev;GO --1.建立归档计划执行 ...