原文链接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的更多相关文章

  1. UOJ #207. 共价大爷游长沙 [lct 异或]

    #207. 共价大爷游长沙 题意:一棵树,支持加边删边,加入点对,删除点对,询问所有点对是否经过一条边 一开始一直想在边权上做文章,或者从连通分量角度考虑,比较接近正解了,但是没想到给点对分配权值所以 ...

  2. [UOJ#207. 共价大爷游长沙]——LCT&随机化

    题目大意: 传送门 给一颗动态树,给出一些路径并动态修改,每次询问一条边是否被所有路径覆盖. 题解: 先%一发myy. 开始感觉不是很可做的样子,发现子树信息无论维护什么都不太对…… 然后打开题目标签 ...

  3. UOJ #207. 共价大爷游长沙

    #207. 共价大爷游长沙 链接:http://uoj.ac/problem/207 题意:给一棵树,要求支持加边.删边.询问一条边是否被所有路径覆盖.同时路径端点集合有加入与删除操作. 想法: 考虑 ...

  4. 【刷题】UOJ #207 共价大爷游长沙

    火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编号为 \(1\) 到 ...

  5. UOJ #207. 共价大爷游长沙(LCT + 异或哈希)

    题目 维护一颗动态树,并维护一个点对集合 \(S\) . 动态查询一条边,是否被集合中所有点对构成的路径包含. \(n \le 100000, m \le 300000\) 题解 orz 前辈 毛爷爷 ...

  6. 数据结构(动态树):UOJ 207 共价大爷游长沙

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABHwAAAJZCAIAAABUW7XHAAAgAElEQVR4nOy93cstx5Xm2f9TXh2EOe

  7. 共价大爷游长沙 lct 维护子树信息

    这个题目的关键就是判断 大爷所有可能会走的路 会不会经过询问的边. 某一条路径经过其中的一条边, 那么2个端点是在这条边的2测的. 现在我们要判断所有的路径是不是都经过 u -> v 我们以u为 ...

  8. 【UOJ#207】共价大爷游长沙

    题目链接 题目描述 火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编 ...

  9. 【UOJ207】共价大爷游长沙(Link-Cut Tree,随机化)

    [UOJ207]共价大爷游长沙(Link-Cut Tree,随机化) 题面 UOJ 题解 这题太神了 \(\%\%\%myy\) 看到动态的维护边很容易的想到了\(LCT\) 然后能否堵住一条路 我们 ...

随机推荐

  1. 更新ocr voting后第二个节点启动不起来

    [+ASM2]@qdcx-db2[/home/grid]$crsctl check crs CRS-4638: Oracle High Availability Services is online ...

  2. HDU 5033

    题意: 给你 N 楼房, 然后给你m个人站在这些楼房之间, 问看到天空的仰角是多少度 思路: 对于每一个人, 算出左边的凸包, 和右边的凸包, 找出最大斜率点, 算角度即可 (我在线算比较费时, 离线 ...

  3. python-函数入门(二)

    一.函数对象 什么是函数? 函数是第一类对象,指的是函数名指向的值(函数)可以被当做数据去使用 1.函数的特性 1.函数可以被引用,即函数可以把值赋值给一个变量 def foo(): print('f ...

  4. IOS 静态库 和 动态库

    库从本质上市一中可执行的二进制格式,可以被载入内存中执行   iOS 中的静态库有 .a 和 .framework 两种形式;  动态库有  .dylib   和  .framework 两种, 后来 ...

  5. 设置外部查找工具来索引 Confluence 6

    任何网页的 crawler  工具都可以被用来索引你的 Confluence 站点中的内容.如果你希望注册用户才能够查看的内容也被索引的话,你需要为你的 Confluence 创建一个只被 crawl ...

  6. gnuradio 创建动态库 libftd3xx.so

    首先还是创建好模块gr-kcd cd gr-kcd 打开CMakeLists.txt cmake_minimum_required(VERSION 2.6) project(gr-kcd CXX C) ...

  7. (不断更新)关于显著性检测的调研-Salient Object Detection: A Survey

    <Salient Object Detection: A Survey>作者:Ali Borji.Ming-Ming Cheng.Huaizu Jiang and Jia Li 基本按照文 ...

  8. GoogLeNet 之 Inception v1 v2 v3 v4

    论文地址 Inception V1 :Going Deeper with Convolutions Inception-v2 :Batch Normalization: Accelerating De ...

  9. JSP 动作

    动作是第三种类型的语法元素,它们被转换成Java 代码来执行操作,如访问一个Java对象或调用方法. 一. useBean useBean将创建一个关联Java对象的脚本变量.这 是早期分离的表示层和 ...

  10. Burp Scanner Report

    1.使用application web 漏洞平台,除此之外还有一款类似的工具 叫做mulidata,其实mulidata功能更好一点. 2.配置之前的问题处理 安装之前要确认 自己之前是否安装过 Ap ...