LCT模板。

Orz了一下大佬的板子

Orz

UPD(10.19):好像理解LCT了。。。

LCT相当与把一个树剖分,分成实边和虚边,对于每一个实链用一个splay维护一下它的深度,然后当你想进行操作的时候就用splay灵活的变更它的深度与父子关系。

其中实边接的两个点父子相认,就是父节点承认有这个子结点,而虚边父节点就不承认有这个子节点。

其中核心操作access,是把x->root路径上的所有边标记成实边,路径上的点项链的其它边标记成虚边。具体实现是从x向上,一直往上跳fa,在splay上断掉当前节点的右儿子,然后接上x->root路径上的它的下一个。

makeroot(x)就是把x作为它的根,这样的话我们可以先access(x),意思是把root->x上的路径变成实的,然后splay(x),再给x打个rev标记,意思是把x的深度调到最浅。

link(x,y)就是先把x弄成根,再在x和y之间连一条虚边。

cut(x,y)就是把x弄成根,access了y,这样的话实链上就只有x和y了,就可以直接断了。

对于这里面的splay的isroot操作,当该节点不是父节点的儿子的时候就说明走到了这个实链的顶端了。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=3e5+5;
int n,m,p[N],sum[N],fa[N],ch[N][2],stk[N];
bool rev[N];
void pushup(int x) {sum[x]=sum[ch[x][0]]^sum[ch[x][1]]^p[x];}
bool ck(int x) {return x==ch[fa[x]][1];}
void pushdown(int x) {if(rev[x]) rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,rev[x]^=1,swap(ch[x][0],ch[x][1]);}
bool isroot(int x) {return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void rotate(int x) {
int old=fa[x],oldf=fa[old];
bool chk=ck(x);
if(!isroot(old)) ch[oldf][ck(old)]=x;
ch[old][chk]=ch[x][chk^1];
fa[ch[old][chk]]=old;
ch[x][chk^1]=old;
fa[old]=x;
fa[x]=oldf;
pushup(old);
pushup(x);
}
void splay(int x) {
int top=0;
stk[++top]=x;
for(int i=x; !isroot(i); i=fa[i]) stk[++top]=fa[i];
for(int i=top; i; i--) pushdown(stk[i]);
for(int f; !isroot(x); rotate(x)) if(!isroot(f=fa[x])) rotate(ck(x)==ck(f)?f:x);
}
void access(int x) {for(int t=0; x; t=x,x=fa[x]) splay(x),ch[x][1]=t,pushup(x);}
void makeroot(int x) {access(x),splay(x),rev[x]^=1;}
int find(int x) {access(x),splay(x);while(ch[x][0])x=ch[x][0];return x;}
void link(int x,int y) {makeroot(x),fa[x]=y;}
void cut(int x,int y) {
makeroot(x);access(y);splay(y);
if(ch[x][0]||ch[x][1]||fa[x]!=y||ch[y][ck(x)^1])return;
ch[y][0]=fa[x]=0;
}
void change(int x,int y) {p[x]=y,access(x),splay(x);}
int query(int x,int y) {makeroot(x),access(y),splay(y);return sum[y];}
int main() {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) scanf("%d",&p[i]);
for(int i=1,opt,x,y; i<=m; i++) {
scanf("%d%d%d",&opt,&x,&y);
switch(opt) {
case 0:printf("%d\n",query(x,y));break;
case 1:if(find(x)!=find(y)) link(x,y);break;
case 2:if(find(x)==find(y)) cut(x,y);break;
case 3:change(x,y);break;
}
}
}

[模板]Link-Cut-Tree的更多相关文章

  1. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  2. 洛谷P3690 [模板] Link Cut Tree [LCT]

    题目传送门 Link Cut Tree 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代 ...

  3. 模板Link Cut Tree (动态树)

    题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联 ...

  4. 洛谷.3690.[模板]Link Cut Tree(动态树)

    题目链接 LCT(良心总结) #include <cstdio> #include <cctype> #include <algorithm> #define gc ...

  5. 【刷题】洛谷 P3690 【模板】Link Cut Tree (动态树)

    题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...

  6. P3690 【模板】Link Cut Tree (动态树)

    P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...

  7. LG3690 【模板】Link Cut Tree (动态树)

    题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...

  8. AC日记——【模板】Link Cut Tree 洛谷 P3690

    [模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...

  9. LG3690 【模板】Link Cut Tree 和 SDOI2008 洞穴勘测

    UPD:更新了写法. [模板]Link Cut Tree 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 后接两个整数(x,y),代表询问从x到y ...

  10. (RE) luogu P3690 【模板】Link Cut Tree

    二次联通门 : luogu P3690 [模板]Link Cut Tree 莫名RE第8个点....如果有dalao帮忙查错的话万分感激 #include <cstdio> #includ ...

随机推荐

  1. [bzoj4487][Jsoi2015]染色_容斥原理

    染色 bzoj-4487 Jsoi-2015 题目大意:给你一个n*m的方格图,在格子上染色.有c中颜色可以选择,也可以选择不染.求满足条件的方案数,使得:每一行每一列都至少有一个格子被染色,且所有的 ...

  2. 项目 cmdb(一)

    Django之ModelForm组件 ModelForm    a.  class Meta:            model,                           # 对应Mode ...

  3. Linux文件查找命令find(转)

    Linux find命令用来在指定目录下查找文件.任何位于参数之前的字符串都将被视为欲查找的目录名.如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件.并且将查找到的子目录 ...

  4. 实现icon和文字垂直居中的两种方法-(vertical-align and line-height)

    方法一:vertical-align 在w3school定义:该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐 百思不得骑姐 然后Google,反正在w3schools上面并没有找到定义 仅 ...

  5. 关于JOS 未对全部内存分页映射之前 物理地址映射问题的思考

    在kern/pmap.c 里面会又以下这段代码,要知道boot_alloc只会分配线性地址,真正建立虚拟页和物理页映射关系的在后面的page_alloc. ////////////////////// ...

  6. CentOS 7通过yum安装fcitx五笔输入法

    CentOS 7通过yum安装fcitx五笔输入法 下面通过了亲測: 1.设置源 Posted in Linux at 三月 5th, 2015 / No Comments ? 增加EPEL源 EPE ...

  7. JSTL函数标签

    tld 文件代码 <?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="ht ...

  8. Android应用开发-护眼提醒-总结篇

    设计初衷: 在学习<第一行代码>的服务那章时,涉及到了alarmmanager的内容.然后笔者当时正好在关注"程序猿怎样保护眼睛"的问题. 于是便自己做了一个demo, ...

  9. Linux系统的命令源码的获取方法

    我们知道,Linux是开源的,它自带的功能强大的命令也是开源的,也就是说.我们能够获得这些命令的源码并研究它.那到底怎样获得系统的命令的源码呢? 命令的源码是一个软件包为单元的,放在一个软件包的源码中 ...

  10. javascript的==和===,以及if(xxx)总结

    转载请注明 本文出自:http://blog.csdn.net/nancle 首先说==和=== 首先说明一个非常特殊的值NaN, typeof(Nav)得到'number',可是NaN不等于不论什么 ...