这个题目的关键就是判断 大爷所有可能会走的路 会不会经过询问的边。

某一条路径经过其中的一条边, 那么2个端点是在这条边的2测的。

现在我们要判断所有的路径是不是都经过 u -> v 我们以u为根节点, 如果所有的路劲的起点 有且仅有一个点在 v 的子树内 我们就可以知道这个边是合法的。

那么我们每次增加路劲之后, 都在2个端点都亦或上某一个值, 每次判断的时候都判断这个v的子树内整颗树的亦或和是不是等于整体亦或和。如果是 那就说明合法。

现在我们用lct维护这个树。

在这个地方我们需要用lct维护子树信息。

普通的lct是维护一条链的。

lct维护子树的话, 我们需要新开一个状态 存下所有的 非偏爱子节点的 的值。

每次切换偏爱子节点的时候, 假设  u 的偏爱子节点为 v 现在转变成x。

那我们就需要把 x的值从非偏爱中取出, 然后在把u的值放入。

这样我们就维护好了这个东西。

代码:

 #include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 5e5 + ;
struct Node{
int rev, rt;
int son[], pre;
int sum, vsum, key;
void init(){
rt = ; rev = pre = son[] = son[] = ;
sum = vsum = key = ;
}
}tr[N];
void Push_Rev(int x){
if(!x) return ;
swap(lch(x), rch(x));
tr[x].rev ^= ;
}
void Push_Up(int x){
if(!x) return ;
tr[x].sum = tr[x].key ^ tr[lch(x)].sum ^ tr[rch(x)].sum ^ tr[x].vsum;
}
void Push_Down(int x){
if(tr[x].rev){
tr[x].rev = ;
Push_Rev(lch(x));
Push_Rev(rch(x));
}
}
void Rev(int x){
if(!tr[x].rt) Rev(tr[x].pre);
Push_Down(x);
}
void rotate(int x){
if(tr[x].rt) return;
int y = tr[x].pre, z = tr[y].pre;
int k = (rch(y) == x);
tr[y].son[k] = tr[x].son[k^];
tr[tr[y].son[k]].pre = y;
tr[x].son[k^] = y;
tr[y].pre = x;
tr[x].pre = z;
if(tr[y].rt) tr[y].rt = , tr[x].rt = ;
else tr[z].son[rch(z) == y] = x;
Push_Up(y);
}
void Splay(int x){
Rev(x);
while(!tr[x].rt){
int y = tr[x].pre, z = tr[y].pre;
if(!tr[y].rt){
if(( x == rch(y) ) != (y == rch(z))) rotate(y);
else rotate(x);
}
rotate(x);
}
Push_Up(x);
}
void Access(int x){
int y = ;
do{
Splay(x);
tr[rch(x)].rt = ;
tr[x].vsum ^= tr[rch(x)].sum;
rch(x) = y;
tr[x].vsum ^= tr[rch(x)].sum;
tr[y].rt = ;
Push_Up(x);
y = x;
x = tr[x].pre;
}while(x);
}
void Make_rt(int x){
Access(x);
Splay(x);
Push_Rev(x);
}
void link(int u, int v){
Make_rt(u);
Access(v);
Splay(v);
tr[u].pre = v;
tr[v].
vsum ^= tr[u].sum;
Push_Up(v);
}
void cut(int u, int v){
Make_rt(u);
Access(v);
Splay(v);
tr[lch(v)].pre = ;
tr[lch(v)].rt = ;
tr[v].pre = ;
lch(v) = ;
Push_Up(v);
}
int a[N], b[N], c[N];
int main(){
int n, m;
scanf("%d%d%d", &n, &n, &m);
int x, y;
for(int i = ; i <= n; i++)
tr[i].init();
for(int i = ; i < n; i++){
scanf("%d%d", &x, &y);
link(x, y);
}
int op, u, v, tot = ;
int jud = ;
for(int i = ; i <= m; i++){
scanf("%d", &op);
if(op == ){
scanf("%d%d%d%d", &x, &y, &u, &v);
cut(x, y);
link(u, v);
}
if(op == ){
++tot;
scanf("%d%d", &a[tot], &b[tot]);
x = a[tot], y = b[tot];
c[tot] = rand()>>|rand();
Make_rt(x);
tr[x].sum ^= c[tot];
tr[x].key ^= c[tot];
Make_rt(y);
tr[y].sum ^= c[tot];
tr[y].key ^= c[tot];
jud ^= c[tot];
}
if(op == ){
scanf("%d", &v);
x = a[v], y = b[v], u = c[v];
Make_rt(x);
tr[x].sum ^= u;
tr[x].key ^= u;
Make_rt(y);
tr[y].sum ^= u;
tr[y].key ^= u;
jud ^= u;
}
if(op == ){
scanf("%d%d", &x, &y);
Make_rt(x);
Access(y);
Splay(x);
if(jud == tr[y].sum) puts("YES");
else puts("NO");
}
}
return ;
}

共价大爷游长沙 lct 维护子树信息的更多相关文章

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

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

  2. UOJ#207. 共价大爷游长沙 LCT

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ207.html 题解 第一次听说 LCT 还可以维护子树信息. 首先对于每一条路径 rand 一个值,分别 ...

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

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

  4. 【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息

    题目描述 给出一棵树和一个点对集合S,多次改变这棵树的形态.在集合中加入或删除点对,或询问集合内的每组点对之间的路径是否都经过某条给定边. 输入 输入的第一行包含一个整数 id,表示测试数据编号,如第 ...

  5. 【LCT维护子树信息】uoj207 共价大爷游长沙

    这道题思路方面就不多讲了,主要是通过这题学一下lct维护子树信息. lct某节点u的子树信息由其重链的一棵splay上信息和若干轻儿子子树信息合并而成. splay是有子树结构的,可以在rotate, ...

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

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

  7. LCT维护子树信息

    有些题目,在要求支持link-cut之外,还会在线询问某个子树的信息.LCT可以通过维护虚边信息完成这个操作. 对于LCT上每个节点,维护两个两sz和si,后者维护该点所有虚儿子的信息,前者维护该点的 ...

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

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

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

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

随机推荐

  1. LinkedHashMap的特殊之处

    一.前言 乍眼一看会怀疑或者问LinkedHashMap与HashMap有什么区别? 它有什么与众不同之处?  由于前面已经有两篇文章分析了HashMap,今天就看看LinkedHashMap.(基于 ...

  2. PHP验证身份证格式

    互联网公司对身份证验证的需求越来越多,然而普通的小公司是无法对接公安部门的身份认证系统的.几乎都是在网上买一些大的互联网公司的一些认证服务.即使是便宜一些的认证价格也达到了10万次/万元.也就是一角钱 ...

  3. hdoj 3732 Ahui Writes Word (多重背包)

    之前在做背包的题目时看到了这道题,一看,大喜,这不是裸裸的01背包吗!!  然后华丽丽的超时,相信很多人也和我一样没有考虑到数据量的大小. 时隔多日,回过头来看这道题,依旧毫无头绪....不过相比之前 ...

  4. 使用RedisMQ 做一次分布式改造

    引言 熟悉TPL Dataflow博文的朋友可能记得这是个单体程序,使用TPL Dataflow 处理工作流任务, 在使用Docker部署的过程中, 有一个问题一直无法回避: 在单体程序部署的瞬间会有 ...

  5. java中什么是继承笔记

    继承 怎样实现继承:1,先提取共有的属性和方法,放到一个类里,这个叫父类.基类.超类        2.编写子类 修饰符 class 子类名 extends 父类名 好处:提高代码的复用性 子类怎么去 ...

  6. Spring入门(七):Spring Profile使用讲解

    1. 使用场景 在日常的开发工作中,我们经常需要将程序部署到不同的环境,比如Dev开发环境,QA测试环境,Prod生产环境,这些环境下的一些配置肯定是不一样的,比如数据库配置,Redis配置,Rabb ...

  7. Spring基础笔记

    Spring带给了我们什么便利? 注解版本的IOC如何玩? 组件注册 组件注册的过程中有哪些过滤规则? 如何控制组件的作用域(单例多例)? 六种注册组件的方式? 生命周期 什么是bean的生命周期 在 ...

  8. 状压DP概念 及例题(洛谷 P1896 互不侵犯)

    状压DP 就是状态压缩DP.所谓状态压缩,就是将一些复杂的状态压缩起来,一般来说是压缩为一个二进制数,用01来表示某一元素的状态. 比如一排灯泡(5个) 我们可以用一串二进制01串来表示他们的状态 1 ...

  9. exported function xxx should have comment or be unexported

    0x00 问题 exported function xxx should have comment or be unexported. 0x01 解决 https://golang.org/s/sty ...

  10. php安装mongo扩展(linux)

    1.首先下载php的mongodb扩展 从http://pecl.php.net/package/mongodb这个网址下载mongodb的扩展源码包 2.解压安装包 tar zxf mongodb- ...