https://www.lydsy.com/JudgeOnline/problem.php?id=3674

用可持久化数组维护并查集的fa数组,

查询时间复杂度为nlognlogn,一个log是并查集的时间复杂度,采用按秩合并的操作,需要注意的是按秩合并的秩意思为当前最大结点下的树的最大深度。

另一个log是主席树查询的时间复杂度

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
int read(){int x = ,f = ;char c = getchar();while (c<'' || c>''){if (c == '-') f = -;c = getchar();}
while (c >= ''&&c <= ''){x = x * + c - '';c = getchar();}return x*f;}
const double eps = 1e-;
const int maxn = 2e5 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
int T[maxn],tot;
struct Tree{
int lt,rt;
int fa,size;
}tree[maxn * ];
int fa[maxn],Size[maxn];
void newnode(int &t){
t = ++tot;
tree[t].lt = tree[t].rt = tree[t].fa = ;
}
void Build(int &t,int l,int r){
newnode(t);
if(l == r){
tree[t].fa = l;
tree[t].size = ;
return;
}
int m = l + r >> ;
Build(tree[t].lt,l,m); Build(tree[t].rt,m + ,r);
}
int query(int t,int l,int r,int x){
if(l == r){
Size[x] = tree[t].size;
return tree[t].fa;
}
int m = l + r >> ;
if(x <= m) return query(tree[t].lt,l,m,x);
else return query(tree[t].rt,m + ,r,x);
}
void update(int &t,int pre,int l,int r,int x){
newnode(t);
tree[t] = tree[pre];
if(l == r){
tree[t].fa = fa[x];
tree[t].size = Size[x];
return;
}
int m = l + r >> ;
if(x <= m) update(tree[t].lt,tree[pre].lt,l,m,x);
else update(tree[t].rt,tree[pre].rt,m + ,r,x);
}
int find(int id,int x){
int f = query(T[id],,N,x);
if(f == x) return x;
return find(id,f);
}
int main(){
//freopen("C.in","r",stdin);
Sca2(N,M);
Build(T[],,N);
int ans = ;
for(int i = ; i <= M; i ++){
int op = read();
if(op == ){
int a = read() ^ ans,b = read() ^ ans;
a = find(i - ,a); b = find(i - ,b);
if(Size[a] > Size[b]) swap(a,b);
fa[a] = b;
update(T[i],T[i - ],,N,a);
if(Size[a] == Size[b]){
Size[b]++; fa[b] = b;
int x;
update(x,T[i],,N,b);
T[i] = x;
}
}else if(op == ){
int k = read() ^ ans;
T[i] = T[k];
}else if(op == ){
T[i] = T[i - ];
int a = read() ^ ans,b = read() ^ ans;
a = find(i,a); b = find(i,b);
ans = (a == b);
if(a == b) puts("");
else puts("");
} }
return ;
}

BZOJ 3674 可持久化并查集的更多相关文章

  1. BZOJ 3674 可持久化并查集加强版(路径压缩版本)

    /* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...

  2. BZOJ 3674 可持久化并查集加强版(按秩合并版本)

    /* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...

  3. BZOJ 3674 可持久化并查集加强版(主席树变形)

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 2515  Solved: 1107 [Submit][Sta ...

  4. bzoj 3674: 可持久化并查集加强版 (启发式合并+主席树)

    Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… ...

  5. BZOJ 3673 可持久化并查集 by zky && BZOJ 3674 可持久化并查集加强版 可持久化线段树

    既然有了可持久化数组,就有可持久化并查集.. 由于上课讲过说是只能按秩合并(但是我也不确定...),所以就先写了按秩合并,相当于是维护fa[]和rk[] getf就是在这棵树中找,直到找到一个点的fa ...

  6. bzoj 3674 可持久化并查集加强版——可持久化并查集

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3674 用主席树维护 fa[ ]  和 siz[ ] .改 fa[ ] 和改 siz[ ] 都 ...

  7. BZOJ 3674: 可持久化并查集加强版

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3674 题意:三种操作:(1)合并ab所在集合:(2)查询ab是否在一个集合:(3) ...

  8. BZOJ 3674 可持久化并查集加强版 可持久化并查集

    题目大意:同3673 强制在线 同3673 仅仅只是慢了一些0.0 这道题仅仅写路径压缩比仅仅写启示式合并要快一点点 两个都写就慢的要死0.0 改代码RE的可能是内存不够 #include<cs ...

  9. BZOJ 3674: 可持久化并查集模板

    Code: #include <cstdio> #include <algorithm> #include <cstring> #include <strin ...

随机推荐

  1. 使用VsCode自带的Emmet语法

    新建html文件,保存之后,输入"!",按Tap(或Enter)键,自动生成HTML结构 标签只要直接输入标签名(不要输入<>),按Tap(或Enter)键自动生成完整 ...

  2. Python简介之探观止矣

    Python是一门什么样的编程语言编程语言主要分为编译型和解释型,静态语言和动态语言,强类型和弱类型,混合语言等.编译型语言:通过编译器把源代码编译(compile)成机器语言,在经过链接(linke ...

  3. NSTimer 不工作 不调用方法

    比如,定义一个NSTimer来隔一会调用某个方法,但这时你在拖动textVIew不放手,主线程就被占用了.timer的监听方法就不调用,直到你松手,这时把timer加到 runloop里,就相当于告诉 ...

  4. Linux学习历程——Centos 7 grep命令

    一.命令简介 grep 命令用于在文本中执行关键词搜索,并显示匹配的结果. 由于grep命令参数很多,这里只列出一些常用的参数. 参数 作用 -b 将可执行文件当作文本文件来搜索 -c 仅显示找到的行 ...

  5. linux 硬盘满了如何处理(转)

    linux 硬盘满了如何处理 事件源于在服务器运行一个脚本程序… 好好的脚本突然报错,还以为脚本出现问题了.细看报错原因(具体报错信息已经忘记了),是没有可用空间.从没遇见过这个情况,怎么办呢? 一. ...

  6. 关于clone(java.lang.Object)重写

    1. 需要实现接口java.lang.Cloneable 2. 重写java.lang.Object的clone 3. clone访问权限扩大为public 4. 不实现(java.lang.Clon ...

  7. 持续代码质量管理-SonarQube-7.3简单使用

    安装了SonarQube以及Sonar Scanner之后,就需要那代码检测了.当然为了方便我们使用已有现成的demo,知道到对应的git地址下载即可. 1. sonar-examples下载 htt ...

  8. LeetCode算法题-Detect Capital(Java实现)

    这是悦乐书的第251次更新,第264篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第118题(顺位题号是520).给定一个单词,你需要判断其中大写字母的使用是否正确.当下 ...

  9. MySQL 数据查询

    SELECT子句:用来指定查询返回字段,星号(*)表示返回所有字段 SELECT  [DISTINCT]*|字段列表        #DISTINCT 用来过滤重复数据 FROM子句:用来指定数据来源 ...

  10. 周末班:Python基础之面向对象基础

    面向对象基础 面向对象和面向过程 编程思想是什么,就是用代码解决现实生活中问题的思路. 面向过程 核心点在过程二字,过程指的是解决问题的步骤,说白了就是先做什么再干什么.这种解决问题的思路就好比是工厂 ...