【BZOJ】3674: 可持久化并查集加强版
题解
感觉全世界都写过只有我没写过
毕竟是板子还是挺简单的,只要用可持久化线段树维护一下数组的形态就好了,每个数组里面维护这个数组的father,和这个点所在树的最长链的深度(如果这个点是根按秩合并要用)
为了避免返回两个值可以直接返回所在线段树节点的编号
代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <bitset>
#define enter putchar('\n')
#define space putchar(' ')
//#define ivorysi
#define pb push_back
#define mo 974711
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define MAXN 200005
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 - '0' + c;
c = getchar();
}
res = res * f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
int N,M;
struct node {
int f,dep,lc,rc;
}tr[MAXN * 80];
int rt[MAXN],Ncnt;
void build(int &u,int l,int r) {
u = ++Ncnt;
if(l == r) {
tr[u].f = l;
tr[u].dep = 1;
return;
}
int mid = (l + r) >> 1;
build(tr[u].lc,l,mid);
build(tr[u].rc,mid + 1,r);
}
int Query(int u,int L,int R,int pos) {
if(L == R) return u;
int mid = (L + R) >> 1;
if(pos <= mid) return Query(tr[u].lc,L,mid,pos);
else return Query(tr[u].rc,mid + 1,R,pos);
}
void Change(int x,int &y,int L,int R,int pos,int v) {
y = ++Ncnt;
tr[y] = tr[x];
if(L == R) {tr[y].f = v;return;}
int mid = (L + R) >> 1;
if(pos <= mid) Change(tr[x].lc,tr[y].lc,L,mid,pos,v);
else Change(tr[x].rc,tr[y].rc,mid + 1,R,pos,v);
}
void Inc_dep(int x,int &y,int L,int R,int pos) {
y = ++Ncnt;
tr[y] = tr[x];
if(L == R) {tr[y].dep++;return;}
int mid = (L + R) >> 1;
if(pos <= mid) Inc_dep(tr[x].lc,tr[y].lc,L,mid,pos);
else Inc_dep(tr[x].rc,tr[y].rc,mid + 1,R,pos);
}
int getfa(int u,int x) {
int p = Query(u,1,N,x);
if(tr[p].f == x) return p;
else return getfa(u,tr[p].f);
}
void Solve() {
read(N);read(M);
build(rt[0],1,N);
int op,a,b;
for(int i = 1 ; i <= M ; ++i) {
read(op);
if(op == 1) {
rt[i] = rt[i - 1];
read(a);read(b);
a = getfa(rt[i],a);b = getfa(rt[i],b);
if(a == b) continue;
if(tr[a].dep < tr[b].dep) Change(rt[i],rt[i],1,N,tr[a].f,tr[b].f);
else if(tr[b].dep < tr[a].dep) Change(rt[i],rt[i],1,N,tr[b].f,tr[a].f);
else {
Change(rt[i],rt[i],1,N,tr[a].f,tr[b].f);
Inc_dep(rt[i],rt[i],1,N,tr[b].f);
}
}
else if(op == 2) {
read(a);
rt[i] = rt[a];
}
else if(op == 3) {
rt[i] = rt[i - 1];
read(a);read(b);
a = getfa(rt[i],a);b = getfa(rt[i],b);
if(a == b) {puts("1");}
else puts("0");
}
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
【BZOJ】3674: 可持久化并查集加强版的更多相关文章
- 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 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 可持久化并查集 by zky && BZOJ 3674 可持久化并查集加强版 可持久化线段树
既然有了可持久化数组,就有可持久化并查集.. 由于上课讲过说是只能按秩合并(但是我也不确定...),所以就先写了按秩合并,相当于是维护fa[]和rk[] getf就是在这棵树中找,直到找到一个点的fa ...
- bzoj 3674 可持久化并查集加强版——可持久化并查集
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3674 用主席树维护 fa[ ] 和 siz[ ] .改 fa[ ] 和改 siz[ ] 都 ...
- BZOJ 3674: 可持久化并查集加强版
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3674 题意:三种操作:(1)合并ab所在集合:(2)查询ab是否在一个集合:(3) ...
- BZOJ 3674 可持久化并查集加强版 可持久化并查集
题目大意:同3673 强制在线 同3673 仅仅只是慢了一些0.0 这道题仅仅写路径压缩比仅仅写启示式合并要快一点点 两个都写就慢的要死0.0 改代码RE的可能是内存不够 #include<cs ...
- 【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日也就是初三暑假要结束的时候就已经能切这种题了%%% 学习了另一种启发式合并的方法,按秩合并,也就是按树的深度合并,实际上是和按树的大小一个道理,但是感觉(至少在这题上)更好 ...
随机推荐
- Shell记录-Shell命令(磁盘)
inux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息. 1.命令格式 df [选项] [文件] Shell ...
- Flash数据的采集方法-搜房房价走势采集
一般来说flash中的数据是不能被现有技术很容易采集到的,但是也不能谈flash色变,要具体问题具体分析,有些flash是可以通过一些分析发现背后的数据.然后采集就变得很容易了. 具体案例:搜房房价走 ...
- python json dumps loads
请看以上图片可知 1. python requests里面返回的是json 字符串, 说白了是字符串.不能直接取里面对应的值. 2. 取值的话,需要把json字符串转换成字典, 用json.loads ...
- 微信小程序开发教程(七)逻辑层——.js详解
逻辑层,是事务逻辑处理的地方.对于小程序而言,逻辑层就是.js脚本文件的集合.逻辑层将数据进行处理后发送给视图层,同时接收视图层的事件反馈. 微信小程序开发框架的逻辑层是由JavaScript编写.在 ...
- layui-laypage模块代码详解
/** layui-v2.4.0 MIT License By https://www.layui.com */;layui.define(function(e) { "use strict ...
- 关于onConfigurationChanged
这两天测试app时,发现一个奇怪问题,app在启动后,Activity会onCreate两次,起初以为是横屏设置导致,随即在Activity中添加了android:configChanges=&quo ...
- 20155303 《Java程序设计》实验一(Java开发环境的熟悉)实验报告
20155303 <Java程序设计>实验一(Java开发环境的熟悉)实验报告 一.实验内容及步骤 (一)使用JDK编译.运行简单的java程序 命令行下的程序开发 步骤一(新建文件夹): ...
- jquery easyui 扩展验证
$.extend($.fn.validatebox.defaults.rules, { idcard : {// 验证身份证 validator : function(value) ...
- C# 反射获取和设置值
/// <summary> /// 遍历泛型 /// </summary> /// <typeparam name="T"></typep ...
- MVC中检测到有潜在危险的 Request.Form 值
在做mvc项目时,当使用xhedit or.ueditor编辑器时,点击提交时,编辑器中的内容会带有html标签提交给服务器,这时就是会报错,出现如下内容: “/”应用程序中的服务器错误. 从客户端( ...