原文链接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. HDU 4455

    题意 : 题目 给你一个序列 , 查询 t ,问  序列 连续 长度为 t 的子区间 的不同数 的和 巧妙的动态规划 数据大, Dp可以 O(n) #include<iostream> # ...

  2. mysql连表分组报错---- sql_mode=only_full_group_by问题解决

    #### sql语句报错问题 #1055 - Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggreg ...

  3. 新建项目虚拟环境及pycharm配置

    基本操作 查询已有的虚拟环境 workon 激活虚拟环境 workon 虚拟环境名 退出虚拟环境 deactivate 删除虚拟环境 rmvirtualenv 虚拟环境名 查看python版本检查 p ...

  4. Android跳转WIFI界面的四种方式

    第一种 Intent intent = new Intent(); intent.setAction("android.net.wifi.PICK_WIFI_NETWORK"); ...

  5. RCNN--目标检测

    原博文:http://www.cnblogs.com/soulmate1023/p/5530600.html 文章简要介绍RCNN的框架,主要包含: 原图-->候选区域生成-->对每个候选 ...

  6. WebSocket服务端和客户端使用

    using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;usi ...

  7. Windows Service 2012 R2 下如何建立ftp服务器

    1.首先在本地机器上创建一个用户!这些用户是用来登录到FTP的!我的电脑右键->管理->本地用户和组->用户->“右键”新建用户->输入用户名和密码再点创建就行了! 2. ...

  8. linux 批量进行:解压缩某一类压缩文件类型的文件

    1: 编写脚本 [oracle@oracle oracle]$ vim unzip.sh ziphome=/u01/app/oracle ziplist=`du -a $ziphome |grep ' ...

  9. JavaScript(JS)之简单介绍

    一.JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言) N ...

  10. PDF如何添加水印,PDF添加水印工具的使用方法

    PDF文件在编辑修改的时候是需要借助工具才可以编辑,PDF文件不像普通的文件可以直接打开编辑,PDF编辑工具是PDF文件进行编辑的重要工具,就以添加水印为例,能够在PDF中添加水印的工具有哪些呢?要怎 ...