UOJ#207. 共价大爷游长沙 LCT
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ207.html
题解
第一次听说 LCT 还可以维护子树信息。
首先对于每一条路径 rand 一个值,分别放在两个端点上,于是询问一条边是否被所有路径的经过就变成了询问某一边所代表的子树是否包含所有路径的端点各一次。于是我求出子树 xor ,并与当前所有路径值的 xor 比较是否相同就可以判断了。
于是接下来就变成了 LCT 维护子树 xor 。
考虑在 LCT 的时候,再对于每一个节点维护其虚儿子的信息。由于 LCT 涉及虚儿子的操作十分少,所以只需要在修改边的虚实关系的时候顺便维护一下就好了。
时间复杂度 $O((n+m)\log n)$ 。
代码
#include <bits/stdc++.h>
#define link __zzd001
using namespace std;
typedef long long LL;
int read(){
int x=0;
char ch=getchar();
while (!isdigit(ch))
ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x;
}
const int N=100005;
int n,m,id;
int fa[N],son[N][2],rev[N],val[N],sum[N];
void pushup(int x){
sum[x]=sum[son[x][0]]^val[x]^sum[son[x][1]];
}
int isroot(int x){
return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
}
int wson(int x){
return son[fa[x]][1]==x;
}
void rotate(int x){
if (isroot(x))
return;
int y=fa[x],z=fa[y],L=wson(x),R=L^1;
if (!isroot(y))
son[z][wson(y)]=x;
fa[x]=z,fa[y]=x,fa[son[x][R]]=y;
son[y][L]=son[x][R],son[x][R]=y;
pushup(y),pushup(x);
}
void pushdown(int x){
if (rev[x]){
swap(son[x][0],son[x][1]);
rev[son[x][0]]^=1;
rev[son[x][1]]^=1;
rev[x]=0;
}
}
void pushadd(int x){
if (!isroot(x))
pushadd(fa[x]);
pushdown(x);
}
void splay(int x){
pushadd(x);
for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
if (!isroot(y))
rotate(wson(x)==wson(y)?y:x);
}
void access(int x){
for (int t=0;x;t=x,x=fa[x]){
splay(x);
val[x]^=sum[son[x][1]]^sum[t];
fa[t]=x,son[x][1]=t;
pushup(x);
}
}
void rever(int x){
access(x),splay(x),rev[x]^=1;
}
void link(int x,int y){
rever(x),rever(y);
fa[x]=y,val[y]^=sum[x];
pushup(y);
}
void cut(int x,int y){
rever(x),access(y),splay(y);
son[y][0]=fa[x]=0;
pushup(y);
}
int randv[N*3],rands=0,cnt=0;
pair <int,int> path[N*3];
int randint(){
int a=rand()&65535,b=rand()&65535;
return (a<<15)^b;
}
int main(){
srand('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I');
id=read(),n=read(),m=read();
for (int i=1;i<n;i++){
int x=read(),y=read();
link(x,y);
}
while (m--){
int opt=read(),x,y,u,v;
if (opt==1){
x=read(),y=read(),u=read(),v=read();
cut(x,y),link(u,v);
}
else if (opt==2){
x=read(),y=read();
int now=randv[++cnt]=randint();
path[cnt]=make_pair(x,y);
rever(x),val[x]^=now,pushup(x);
rever(y),val[y]^=now,pushup(y);
rands^=now;
}
else if (opt==3){
u=read();
int now=randv[u];
x=path[u].first,y=path[u].second;
rever(x),val[x]^=now,pushup(x);
rever(y),val[y]^=now,pushup(y);
rands^=now;
}
else if (opt==4){
x=read(),y=read();
rever(x);
access(y);
splay(y);
puts(rands==sum[x]?"YES":"NO");
}
}
return 0;
}
UOJ#207. 共价大爷游长沙 LCT的更多相关文章
- UOJ #207. 共价大爷游长沙 [lct 异或]
#207. 共价大爷游长沙 题意:一棵树,支持加边删边,加入点对,删除点对,询问所有点对是否经过一条边 一开始一直想在边权上做文章,或者从连通分量角度考虑,比较接近正解了,但是没想到给点对分配权值所以 ...
- [UOJ#207. 共价大爷游长沙]——LCT&随机化
题目大意: 传送门 给一颗动态树,给出一些路径并动态修改,每次询问一条边是否被所有路径覆盖. 题解: 先%一发myy. 开始感觉不是很可做的样子,发现子树信息无论维护什么都不太对…… 然后打开题目标签 ...
- UOJ #207. 共价大爷游长沙
#207. 共价大爷游长沙 链接:http://uoj.ac/problem/207 题意:给一棵树,要求支持加边.删边.询问一条边是否被所有路径覆盖.同时路径端点集合有加入与删除操作. 想法: 考虑 ...
- 【刷题】UOJ #207 共价大爷游长沙
火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编号为 \(1\) 到 ...
- UOJ #207. 共价大爷游长沙(LCT + 异或哈希)
题目 维护一颗动态树,并维护一个点对集合 \(S\) . 动态查询一条边,是否被集合中所有点对构成的路径包含. \(n \le 100000, m \le 300000\) 题解 orz 前辈 毛爷爷 ...
- 数据结构(动态树):UOJ 207 共价大爷游长沙
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABHwAAAJZCAIAAABUW7XHAAAgAElEQVR4nOy93cstx5Xm2f9TXh2EOe
- 共价大爷游长沙 lct 维护子树信息
这个题目的关键就是判断 大爷所有可能会走的路 会不会经过询问的边. 某一条路径经过其中的一条边, 那么2个端点是在这条边的2测的. 现在我们要判断所有的路径是不是都经过 u -> v 我们以u为 ...
- 【UOJ#207】共价大爷游长沙
题目链接 题目描述 火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编 ...
- 【UOJ207】共价大爷游长沙(Link-Cut Tree,随机化)
[UOJ207]共价大爷游长沙(Link-Cut Tree,随机化) 题面 UOJ 题解 这题太神了 \(\%\%\%myy\) 看到动态的维护边很容易的想到了\(LCT\) 然后能否堵住一条路 我们 ...
随机推荐
- Golang 优化之路——bitset
写在前面 开发过程中会经常处理集合这种数据结构,简单点的处理方法都是使用内置的map实现.但是如果要应对大量数据,例如,存放大量电话号码,使用map占用内存大的问题就会凸显出来.内存占用高又会带来一些 ...
- springboot:接收date类型的参数
今天有个postmapping方法,地址都正确,就是死活进不去,真是奇怪了. 终于从日志中得出些端倪,见下: 只有这个属性报错,恰恰这个属性是Date型. 这句话说得更清楚: "defaul ...
- js 对象的循环
var car = {type:"Fiat", model:500, color:"white"}; var arr = array(); for(i in c ...
- vscode开发c#
转载自: http://www.cnblogs.com/lxhbky/p/6673230.html http://www.cnblogs.com/lxhbky/p/6692065.html 一.环境安 ...
- javascript中的字符串对象
1.javascript的对象的概念 在javascript中,除了null和undefined以处,其他的数据类型都被定义成了对象 也可以用创建对象的方法定义变量,string,math,array ...
- Java并发编程基础-ReentrantLock的机制
同步锁: 我们知道,锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源,在Lock接口出现之前,Java应用程序只能依靠synchronized关键字来实现同步锁 ...
- HTML中body元素的属性
body元素的属性 属性 描述 text 设定页面文字颜色 bgcolor 设定页面背景颜色 background 设定页面背景图像 bgproperties 设定页面的背景图像为固定状态(不随页面的 ...
- 在 Python 中使用 JSON
在 Python 中使用 JSON 本教程将会教我们如何使用 Python 编程语言编码和解码 JSON.让我们先来准备环境以便针对 JSON 进行 Python 编程. 环境 在我们使用 Pytho ...
- 20165206 2017-2018-2 《Java程序设计》第6周学习总结
20165206 2017-2018-2 <Java程序设计>第6周学习总结 教材学习内容总结 String类:可以被直接使用,不可以有子类. String对象:可以使用String类声明 ...
- MySql中 delimiter 详解
转载于:http://blog.csdn.net/yuxin6866/article/details/52722913 其实就是告诉MySQL解释器,该段命令是否已经结束了,mysql是否可以执行了. ...