我是萌萌的任意门

可持久化并查集的模板题……

做法好像很多,可以标号法,可以森林法。

本来有O(mloglogn)的神算法(按秩合并+倍增),然而我这种鶸渣就只会写O(mlog2n)的民科算法……再加上人傻常数大如狗,速度简直虚死……

言归正传,鉴于标号法用的不多,这里用的是森林法。又由于并查集的路径压缩只能均摊logn,如果可持久化一下就废了。所以路径压缩大可不写,正好偷偷懒。

当然,路径压缩都省了,那按秩合并就不能不写了(要不然为啥要出加强版……)。然而我太鶸,不会写按秩合并,一向都是用按大小合并代替的……不过效果还不错,复杂度好像也是个log。

可持久化数组好像有用vector记录修改的神写法,然而我这种鶸渣只会写可持久化线段树……本来就是nlogn了,再乘上一个logn,运行时间实在感人……

总之,写的是可持久化线段树+按秩合并+暴力找父亲(不过貌似大家都是写的按秩合并暴力?然而明明同样O(mlog2n)的算法我就是最慢的那个……)。代码丑,不愿看……就算了……

 /**************************************************************
Problem: 3674
User: hzoier
Language: C++
Result: Accepted
Time:1636 ms
Memory:201612 kb
****************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
int findroot(int);
void mergeset(int,int);
void build(int,int,int&);
void modify(int,int,int&);
void query(int,int,int);
int copy(int);
int lc[maxn<<],rc[maxn<<],a[maxn<<],b[maxn<<],root[maxn],cnt=;
int n,m,d,x,y,k,prt,size,now,ans=;
int main(){
scanf("%d%d",&n,&m);
build(,n,root[]);
for(now=;now<=m;now++){
scanf("%d",&d);
if(d==){
scanf("%d%d",&x,&y);
x^=ans;y^=ans;
root[now]=copy(root[now-]);
mergeset(x,y);
}
else if(d==){
scanf("%d%d",&x,&y);
x^=ans;y^=ans;
root[now]=copy(root[now-]);
printf("%d\n",ans=(int)(findroot(x)==findroot(y)));
}
else{
scanf("%d",&x);
x^=ans;
root[now]=copy(root[x]);
}
}
return ;
}
int findroot(int x){
for(;;){
k=x;
query(,n,root[now]);
if(prt==x)return x;
x=prt;
}
return x;
}
void mergeset(int x,int y){
x=findroot(x);y=findroot(y);
if(x==y)return;
k=x;
query(,n,root[now]);
int sx=size;
k=y;
query(,n,root[now]);
if(sx>size)swap(x,y);
sx+=size;
size=;
k=x;
prt=y;
modify(,n,root[now]);
k=y;
size=sx;
modify(,n,root[now]);
}
void build(int l,int r,int &rt){
rt=++cnt;
if(l==r){
a[rt]=l;
b[rt]=;
return;
}
int mid=(l+r)>>;
build(l,mid,lc[rt]);
build(mid+,r,rc[rt]);
}
void modify(int l,int r,int &rt){
rt=copy(rt);
if(l==r){
if(prt)a[rt]=prt;
if(size)b[rt]=size;
return;
}
int mid=(l+r)>>;
if(k<=mid)modify(l,mid,lc[rt]);
else modify(mid+,r,rc[rt]);
}
void query(int l,int r,int rt){
if(l==r){
prt=a[rt];
size=b[rt];
return;
}
int mid=(l+r)>>;
if(k<=mid)query(l,mid,lc[rt]);
else query(mid+,r,rc[rt]);
}
int copy(int rt){
int x=++cnt;
lc[x]=lc[rt];
rc[x]=rc[rt];
a[x]=a[rt];
b[x]=b[rt];
return x;
}

尽头和开端,总有一个在等你。

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

  1. bzoj3673可持久化并查集 by zky&&bzoj3674可持久化并查集加强版

    bzoj3673可持久化并查集 by zky 题意: 维护可以恢复到第k次操作后的并查集. 题解: 用可持久化线段树维护并查集的fa数组和秩(在并查集里的深度),不能路径压缩所以用按秩启发式合并,可以 ...

  2. BZOJ3674: 可持久化并查集加强版

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3674 题解:主要是可持久化的思想.膜拜了一下hzwer的代码后懂了. 其实本质是可持久化fa数 ...

  3. 2019.01.21 bzoj3674: 可持久化并查集加强版(主席树+并查集)

    传送门 题意:维护可持久化并查集,支持在某个版本连边,回到某个版本,在某个版本 询问连通性. 思路: 我们用主席树维护并查集fafafa数组,由于要查询历史版本,因此不能够用路径压缩. 可以考虑另外一 ...

  4. bzoj3673 bzoj3674可持久化并查集

    并查集都写不来了qwq 之前写的是错的 sz的初值都是0,这样怎么加就都是0了,水这道题还是可以,但是加强版就过不了了 #include<cstdio> #include<cstri ...

  5. [BZOJ3674]可持久化并查集加强版&[BZOJ3673]可持久化并查集 by zky

    思路: 用主席树维护并查集森林,每次连接时新增结点. 似乎并不需要启发式合并,我随随便便写了一个就跑到了3674第一页?3673是这题的弱化版,本来写个暴力就能过,现在借用加强版的代码(去掉异或),直 ...

  6. BZOJ3674 可持久化并查集加强版 可持久化 并查集

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3674 题意概括 n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的 ...

  7. 【可持久化数组】【rope】bzoj3673 bzoj3674 可持久化并查集 by zky

    rope教程:http://blog.csdn.net/iamzky/article/details/38348653 Code(bzoj3673): #include<cstdio> # ...

  8. BZOJ3674可持久化并查集(模板)

    没什么可说的,就是一个可持久化线段树维护一个数组fa以及deep按秩合并好了 注意一下强制在线 蒟蒻的我搞了好长时间QAQ 贴代码: #include<cstdio> #include&l ...

  9. bzoj3673 & bzoj3674 & 洛谷P3402 可持久化并查集

    题目:bzoj3673:https://www.lydsy.com/JudgeOnline/problem.php?id=3673 bzoj3674:https://www.lydsy.com/Jud ...

随机推荐

  1. 分区表/etc/fstab格式

    $ more /etc/fstabUUID=94e4e384-0ace-437f-bc96-057dd64f42ee / ext4 defaults,barrier=0 1 1tmpfs        ...

  2. jQuery的一些常用的方法(转载)

    操作元素的样式 主要包括以下几种方式: $("#msg").css("background"); //返回元素的背景颜色 $("#msg") ...

  3. 转 android 从底部弹出一个popuwindow,渐入渐出效果。我这里是用在购物车需要选择购买选项的操作。

    最近要改客户端,需要实现一个从底部弹出的popuwindow,像我这种渣渣android技术,能整出popuwindow但是整不出动画,百度之,记录一下. 从下面这个地址转的 http://blog. ...

  4. 【Python】[面向对象高级编程] 多成继承,定制类,使用枚举

    1.多成继承 class SmallDog(Animal,Dog) pass MixIn就是一种常见的设计. 2.定制类类似__slots__这种形如 __xxx__ 的变量或者函数名,在python ...

  5. 数据结构图文解析之:直接插入排序及其优化(二分插入排序)解析及C++实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  6. VsFtpd服务配置简明笔记

    Ftp服务是最常用的文件传输方式,把配置步骤记录下来,以备将来使用. 1.用YUM安装VsFtpd服务:[root@Redis usr]# yum install vsftpd 2.安装完成后启动Vs ...

  7. ED2k Resource

    http://www.lwkk.com/ http://www.ed2000.com/

  8. Linux系统下的程序开发之:命名规范

    2016年12月13日16:19:53 ------------------------------- 不能使用类似驼峰法的命名文件:dingdanOrder.html 这样的命名,会让系统无法找到目 ...

  9. JS-抽奖系统-实现原理

    有本事中奖的,过来找我换红包!!哈哈!! <meta charset="UTF-8"> <title>抽奖系统</title> <styl ...

  10. 使用 Eclipse 调试 Java 程序的 10 个技巧

    你应该看过一些如<关于调试的N件事>这类很流行的帖子 .假设我每天花费1小时在调试我的应用程序上的话,那累积起来的话也是很大量的时间.由于这个原因,用这些时间来重视并了解所有使我们调试更方 ...