[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:后接两 ...
随机推荐
- hackme.inndy.tw - pyyy - Writeup
hackme.inndy.tw - pyyy - Writeup 0x01 反编译 1.第一次尝试的时候我直接在线反编译,部分结果如下. for (i, f) in enumerate(F): n = ...
- C语言第一次博客作业 陈张鑫
一,PTA实验作业 题目1.温度转换 本题要求编写程序,计算华氏温度150°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验代 ...
- 关于Mac OS 使用GIT的引导
1. 下载Git installer 链接地址:https://ncu.dl.sourceforge.net/project/git-osx-installer/git-2.14.1-intel-un ...
- C语言——第四次作业
题目 题目一:计算分段函数 1.实验代码 #include <stdio.h> int main() { double x,y; scanf("%lf",&x) ...
- C语言——第三次作业
题目1.A乘以B 1.实验代码 #include <stdio.h> int main() { int A,B,C; scanf("%d %d",&A,& ...
- python实现京东秒杀
# _*_coding:utf-8_*_ from selenium import webdriver import datetime import time driver = webdriver.C ...
- python的测试
测试 知识点 单元测试概念 使用 unittest 模块 测试用例的编写 异常测试 测试覆盖率概念 使用 coverage 模块 实验步骤 1. 应该测试什么? 如果可能的话,代码库中的所有代码都要测 ...
- 织梦cms/dedecms清理冗余废弃未引用图片方法
原理描述: 在原有织梦后台菜单中增加"清理冗余图片按钮",实现清理冗余图片的功能. 操作步骤: 1. 打开后台dede\sys_sql_query.php代码 在该文件中搜索如下代 ...
- 利用Node的chokidar 监听文件改变的文件。
最近维护一个项目.每次改完东西,都要上传到服务器.然后有时候就忘记一些东西,于是就想有没有可以方法能监听文件的改变.然后我再利用程序把更改的文件一键上传到服务器. 于是就找到了nodejs 的chok ...
- javascript改变style样式和css样式
转载 在很多情况下,都需要对网页上元素的样式进行动态的修改.在JavaScript中提供几种方式动态的修改样式,下面将介绍方法的使用.效果.以及缺陷. 1.使用obj.className来修改样式表的 ...