[Luogu 3690]【模板】Link Cut Tree (动态树)
Description
给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。
0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。
1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
3:后接两个整数(x,y),代表将点X上的权值变成Y。
Input
第1行两个整数,分别为N和M,代表点数和操作数。
第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。
第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。
Output
对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。
Sample Input
3 3
1
2
3
1 1 2
0 1 2
0 1 1
Sample Output
3
1
HINT
数据范围: $ 1 \leq N, M \leq 3 \cdot {10}^5 $
题解
维护$xor$和维护子树大小类似。
这道题用到的技巧:
找根:$access(o)$及$splay(o)$后一直往左走。最后一个节点就是根。(理由:由于$LCT$中$splay$的性质:按深度作为键值);
判断是否之间有边:再$cut$之前,判断根的左儿子是否是另外一个点。(理由:若存在边,则包含这条边的$splay$只有两个节点)。
//It is made by Awson on 2017.12.28
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define LD long double
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
const int N = 3e5; struct Link_Cut_Tree {
int ch[N+][], pre[N+], val[N+], xr[N+], isrt[N+], rev[N+];
void pushup(int o) {
if (!o) return;
xr[o] = xr[ch[o][]]^xr[ch[o][]]^val[o];
}
void pushdown(int o) {
if (!o || !rev[o]) return;
int ls = ch[o][], rs = ch[o][];
swap(ch[ls][], ch[ls][]), swap(ch[rs][], ch[rs][]);
rev[ls] ^= , rev[rs] ^= , rev[o] = ;
}
void push(int o) {
if (!isrt[o]) push(pre[o]);
pushdown(o);
}
void rotate(int o, int kind) {
int p = pre[o];
ch[p][!kind] = ch[o][kind], pre[ch[o][kind]] = p;
if (isrt[p]) isrt[o] = , isrt[p] = ;
else ch[pre[p]][ch[pre[p]][] == p] = o;
pre[o] = pre[p];
ch[o][kind] = p, pre[p] = o;
pushup(p), pushup(o);
}
void splay(int o) {
push(o);
while (!isrt[o]) {
if (isrt[pre[o]]) rotate(o, ch[pre[o]][] == o);
else {
int p = pre[o], kind = ch[pre[p]][] == p;
if (ch[p][kind] == o) rotate(o, !kind), rotate(o, kind);
else rotate(p, kind), rotate(o, kind);
}
}
}
void access(int o) {
int y = ;
while (o) {
splay(o);
xr[o] ^= xr[ch[o][]];
isrt[ch[o][]] = , isrt[ch[o][] = y] = ;
pushup(o);
o = pre[y = o];
}
}
void makeroot(int o) {
access(o), splay(o);
rev[o] ^= , swap(ch[o][], ch[o][]);
}
int find(int o) {
access(o), splay(o);
while (ch[o][]) o = ch[o][];
return o;
}
void link(int x, int y) {
int p = find(x), q = find(y);
if (p == q) return;
makeroot(x); pre[x] = y;
}
void cut(int x, int y) {
makeroot(x), access(y), splay(y);
if (ch[y][] != x) return;
xr[y] ^= xr[x], ch[y][] = pre[x] = , isrt[x] = ;
}
int query(int x, int y) {
makeroot(x), access(y), splay(y);
return xr[y];
}
void update(int o, int key) {
makeroot(o); val[o] = key; pushup(o);
}
}T;
int n, m, x, opt, y; void work() {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++) {
scanf("%d", &x);
T.val[i] = T.xr[i] = x, T.isrt[i] = ;
}
while (m--) {
scanf("%d%d%d", &opt, &x, &y);
if (opt == ) printf("%d\n", T.query(x, y));
else if (opt == ) T.link(x, y);
else if (opt == ) T.cut(x, y);
else T.update(x, y);
}
}
int main() {
work();
return ;
}
[Luogu 3690]【模板】Link Cut Tree (动态树)的更多相关文章
- 洛谷.3690.[模板]Link Cut Tree(动态树)
题目链接 LCT(良心总结) #include <cstdio> #include <cctype> #include <algorithm> #define gc ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- Link Cut Tree 动态树 小结
动态树有些类似 树链剖分+并查集 的思想,是用splay维护的 lct的根是动态的,"轻重链"也是动态的,所以并没有真正的轻重链 动态树的操作核心是把你要把 修改/询问/... 等 ...
- LCT(link cut tree) 动态树
模板参考:https://blog.csdn.net/saramanda/article/details/55253627 综合各位大大博客后整理的模板: #include<iostream&g ...
- 洛谷P3690 Link Cut Tree (动态树)
干脆整个LCT模板吧. 缺个链上修改和子树操作,链上修改的话join(u,v)然后把v splay到树根再打个标记就好. 至于子树操作...以后有空的话再学(咕咕咕警告) #include<bi ...
- 洛谷P3690 [模板] Link Cut Tree [LCT]
题目传送门 Link Cut Tree 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代 ...
- 模板Link Cut Tree (动态树)
题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联 ...
- 【刷题】洛谷 P3690 【模板】Link Cut Tree (动态树)
题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
- LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板
P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...
随机推荐
- Maven学习笔记一
maven是apache下的一个开源项目,是纯java开发,并且只是用来管理java项目的. Maven好处 1.普通的传统项目,包含jar包,占用空间很大.而Maven项目不包含jar包,所以占用空 ...
- 【Alpha版本】冲刺阶段 - Day3 - 逆风
今日进展 袁逸灏:右上角两个按键的添加与实现监听(5h) 刘伟康:继续借鉴其他 alpha 冲刺博客,由于我们组的App原型可以在 alpha 阶段完成,所以不需要墨刀工具展示原型(2h) 刘先润:更 ...
- 团队作业4——第一次项目冲刺(Alpha版本)11.18
a. 提供当天站立式会议照片一张 举行站立式会议,讨论项目安排: 整理各自的任务汇报: 全分享遇到的困难一起讨论: 讨论接下来的计划: b. 每个人的工作 (有work item 的ID) 1.前两天 ...
- 记一次jar包冲突
题记:永远不要在同一个项目中,引用不同版本的两个jar包,否则,这可能就是一个大坑. 在做网校项目的时候,帮助中心要使用lucene,所以就引入了lucene-5.5.1的包,删掉了原先存在于项目中的 ...
- [知识梳理]课本1&2.1-2.5
面向对象的语言 出发点:更直接地描述客观世界中存在的事物(对象)以及它们之间的关系. 特点: 是高级语言. 将客观事物看作具有属性和行为的对象. 通过抽象找出同一类对象的共同属性和行为,形成类. 通过 ...
- 第四篇:用IntelliJ IDEA 搭建基于jersey的RESTful api
编译器:Intellij IDEA 系统环境: MAC OS 相关技术:Maven.tomcat 7.jdk8 1.创建项目 首先创建一个web Application项目(这里我们打算用maven引 ...
- day-6 机器学习概念及应用
学习玩Python基础语法,今天开始进行机器学习,首先了解下机器学习和深度学习的一些基本概念和术语: 1. 机器学习概念及应用 2. 深度学习概念及应用 3. 机器学习基本术语及举例 4. 机 ...
- Oracle闪回技术
(一)闪回技术概要 闪回技术是数据库备份与恢复的重要补充手段,主要包括以下7种特性: 特性 原理 数据库支持 闪回查询(Flashback Query) 利用undo表空间中的回退信息,查询过去某个时 ...
- $.ajax 中的contentType
$.ajax 中的contentType 在 cnodejs.org 论坛中有一个问题,让我也很奇怪,说是 $.ajax 设置数据类型 applicaiton/json之后,服务器端(express) ...
- CRC 校验
匠心零度 转载请注明原创出处,谢谢! 说明 上篇RocketMQ(二):RPC通讯介绍了rocketmq的一些rpc细节,其实这些内容不仅仅是rocketmq内容,任何通信模块基本都是类似的,这块内容 ...