共价大爷游长沙 lct 维护子树信息
这个题目的关键就是判断 大爷所有可能会走的路 会不会经过询问的边。
某一条路径经过其中的一条边, 那么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 维护子树信息的更多相关文章
- UOJ #207. 共价大爷游长沙 [lct 异或]
#207. 共价大爷游长沙 题意:一棵树,支持加边删边,加入点对,删除点对,询问所有点对是否经过一条边 一开始一直想在边权上做文章,或者从连通分量角度考虑,比较接近正解了,但是没想到给点对分配权值所以 ...
- UOJ#207. 共价大爷游长沙 LCT
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ207.html 题解 第一次听说 LCT 还可以维护子树信息. 首先对于每一条路径 rand 一个值,分别 ...
- [UOJ#207. 共价大爷游长沙]——LCT&随机化
题目大意: 传送门 给一颗动态树,给出一些路径并动态修改,每次询问一条边是否被所有路径覆盖. 题解: 先%一发myy. 开始感觉不是很可做的样子,发现子树信息无论维护什么都不太对…… 然后打开题目标签 ...
- 【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息
题目描述 给出一棵树和一个点对集合S,多次改变这棵树的形态.在集合中加入或删除点对,或询问集合内的每组点对之间的路径是否都经过某条给定边. 输入 输入的第一行包含一个整数 id,表示测试数据编号,如第 ...
- 【LCT维护子树信息】uoj207 共价大爷游长沙
这道题思路方面就不多讲了,主要是通过这题学一下lct维护子树信息. lct某节点u的子树信息由其重链的一棵splay上信息和若干轻儿子子树信息合并而成. splay是有子树结构的,可以在rotate, ...
- 【刷题】UOJ #207 共价大爷游长沙
火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编号为 \(1\) 到 ...
- LCT维护子树信息
有些题目,在要求支持link-cut之外,还会在线询问某个子树的信息.LCT可以通过维护虚边信息完成这个操作. 对于LCT上每个节点,维护两个两sz和si,后者维护该点所有虚儿子的信息,前者维护该点的 ...
- 【UOJ207】共价大爷游长沙(Link-Cut Tree,随机化)
[UOJ207]共价大爷游长沙(Link-Cut Tree,随机化) 题面 UOJ 题解 这题太神了 \(\%\%\%myy\) 看到动态的维护边很容易的想到了\(LCT\) 然后能否堵住一条路 我们 ...
- UOJ #207. 共价大爷游长沙
#207. 共价大爷游长沙 链接:http://uoj.ac/problem/207 题意:给一棵树,要求支持加边.删边.询问一条边是否被所有路径覆盖.同时路径端点集合有加入与删除操作. 想法: 考虑 ...
随机推荐
- 【OpenCV-ANN神经网络自动驾驶】树莓派OpenCV神经网络自动驾驶小车【源码+实物】
没错!这个是我的毕业设计!!! 整个电子信息学院唯一一个优秀毕业设计 拿到这里炫耀了 实物如下: 电脑端显示效果: 自动驾驶实现过程: 1. 收集图像数据.建立局域网,让主机和Raspberry Pi ...
- 定制开发kubernetes流程
kubernetes集群三步安装 概述 本文介绍如何对kubernetes进行二次开发,仓库如何管理,git分支如何管理,怎样利用CI去编译与发布以及如何给社区贡献代码等,结合实际例子,望对大家有所帮 ...
- 【React踩坑记四】React项目中引入并使用js-xlsx上传插件(结合antdesign的上传组件)
最近有一个前端上传并解析excel/csv表格数据的需求. 于是在github上找到一个14K star的前端解析插件 github传送门 官方也有,奈何实在太过于浅薄.于是做了以下整理,避免道友们少 ...
- java 各基本类型转 bytes 数组
java 将 基本类型转byte[] 数组时,需考虑大端小端问题 1. 大端格式下,基本类型与byte[]互转 BigByteUtil.java package com.ysq.util; impor ...
- Linux fuser工具使用方法介绍
引言 fuser是linux中较常用的工具,"fuser"——从其名称我们可以看出该工具的用途:查询给定文件或目录的用户或进程信息. 除查询文件相关信息之外,使用fuser还能向进 ...
- 【原创实践】U大师启动安装windows XP
1:使用U大师3.0版制作启动U盘,拷贝windows xp或者win7的原版安装iso(zh-hans_windows_xp_professional_with_service_pack_3_x86 ...
- 如何获取app中的toast
前言 Toast是什么呢?在这个手机飞速发展的时代,app的种类也越来越多,那们在日常生活使用中,经常会发现,当你在某个app的输入框输入非法字符或者非法执行某个流程时,经常看到系统会给你弹出一个黑色 ...
- Linux--shell编程原理--03
一.编程原理: 1.编程介绍: 计算机只能识别二进制指令 程序=指令+数据 根据服务的重心不同,我们分为面向过程编程,面向对象编程: a) 面向过程:侧重于指令的编程语言 b) 面向对象:侧重于数据的 ...
- Hadoop - YARN Introduce
YARN Introduce 1. MapReduce1.0缺陷 (1)存在单点故障 (2)JobTracker"大包大揽"导致任务过重(任务多时内存开销大,上限4000节点) ( ...
- 100天搞定机器学习|Day21 Beautiful Soup
前情回顾 机器学习100天|Day1数据预处理 100天搞定机器学习|Day2简单线性回归分析 100天搞定机器学习|Day3多元线性回归 100天搞定机器学习|Day4-6 逻辑回归 100天搞定机 ...