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\) 然后能否堵住一条路 我们 ...
随机推荐
- mybatis:延迟加载时不要在get/set方法上面添加final关键字(原创)
1.mybatis-config.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ...
- css3 曲线阴影,翘边阴影
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- sleep()和wait()的区别及wait方法的一点注意事项
一.查看API sleep是Thread类的方法,导致此线程暂停执行指定时间,给其他线程执行机会,但是依然保持着监控状态,过了指定时间会自动恢复,调用sleep方法不会释放锁对象. 当调用sleep方 ...
- Java_解惑
书名 ================================================================================================= ...
- js原生回到顶部,并平滑过渡---- 记录
window.scrollTo({ top: 0, behavior: 'smooth', });
- shell中的ps命令详解
ps简介:Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的 ...
- LeetCode(122):卖股票的最佳时机 II
Easy! 题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参 ...
- ES6 Promise 全面总结
转载:点击查看原文 ES6 Promise对象 ES6中,新增了Promise对象,它主要用于处理异步回调代码,让代码不至于陷入回调嵌套的死路中. @-v-@ 1. Promise本质 Promise ...
- requests中get和post传参
get请求 get(url, params=None, **kwargs) requests实现get请求传参的两种方式 方式一: import requests url = 'http://www. ...
- 修改ElementUI源码样式
参考:https://segmentfault.com/a/1190000010932321