https://blog.csdn.net/saramanda/article/details/55253627

https://blog.csdn.net/CHHNZ/article/details/55504875

lct模板

 #include<cstdio>
#include<algorithm>
using namespace std;
namespace LCT
{
struct Node
{
Node *ch[],*fa;
bool rev;
int dat,xorx;
}nodes[];
int mem;
Node *getnode()
{
return nodes+(mem++);
}
bool isroot(Node *x)
{
return (!x->fa)||((x->fa->ch[]!=x)&&(x->fa->ch[]!=x));
}
void upd(Node *x)
{
x->xorx=(x->ch[]?x->ch[]->xorx:)^(x->ch[]?x->ch[]->xorx:)^x->dat;
}
void pd(Node *x)
{
if(x->rev)
{
swap(x->ch[],x->ch[]);
if(x->ch[]) x->ch[]->rev^=;
if(x->ch[]) x->ch[]->rev^=;
x->rev=;
}
}
bool gson(Node *o) {return o==o->fa->ch[];}//获得是父亲的左儿子(返回0)还是右儿子(1),要求保证存在父亲
void rotate(Node *o,bool d)
//在o子树中执行d=0左旋,d=1右旋,在旋转前不标记下传,并将o父节点的对应子节点由o变为需要值,要求保证存在子树(!d)
{
Node *k=o->ch[!d];if(!isroot(o)) o->fa->ch[gson(o)]=k;//注意这一句修改o父节点的要写在前面,曾经出过错调了一会
o->ch[!d]=k->ch[d];k->ch[d]=o;
upd(o);upd(k);
k->fa=o->fa;o->fa=k;if(o->ch[!d]) o->ch[!d]->fa=o;
}
Node *st[];int top;
void solvetag(Node *o)
{
while(!isroot(o)) st[++top]=o,o=o->fa;
st[++top]=o;
while(top) pd(st[top--]);
}
void splay(Node *o)
{
solvetag(o);
Node *fa,*fafa;bool d1,d2;
while(!isroot(o))
{
fa=o->fa;d1=(o==fa->ch[]);
if(isroot(fa)) rotate(fa,d1);
else
{
fafa=o->fa->fa;d2=(fa==fafa->ch[]);//要保证fa不是root之后才能获取这两个值,曾错过
if(d1==d2) rotate(fafa,d1),rotate(fa,d1);//zig-zig,两次相同方向的单旋,先把父亲转上去,再把自己转上去
else rotate(fa,d1),rotate(fafa,d2);//zig-zag,两次相反方向的单旋,连续两次把自己转上去
}
}
}
void access(Node *o)
{
for(Node *lst=NULL;o;lst=o,o=o->fa)
{
splay(o);//此处不pushdown是由于splay中保证进行过了
o->ch[]=lst;upd(o);//注意upd
}
}
Node *gtop(Node *o)
{
access(o);splay(o);
for(;o->ch[];o=o->ch[],pd(o));//此处不在开始前pushdown(o)是由于splay中保证进行过了
splay(o);return o;//听说这里不splay一下也很难卡掉
}
void mtop(Node *o) {access(o);splay(o);o->rev^=;}
void link(Node *x,Node *y)
{
if(gtop(x)==gtop(y)) return;
mtop(y);y->fa=x;
}
void cut(Node *x,Node *y)
{
mtop(x);access(y);splay(y);
if(y->ch[]!=x||x->ch[]) return;//如果x、y之间直接有边,那么上面一行的操作之后应当是x与y在单独一棵splay中,那么一定保证y左子节点是x且x没有右子节点
x->fa=y->ch[]=NULL;//注意,改的是x的父亲和y的子节点(虽然x的确是树的根,但是此时在splay上是y的子节点,不能搞混)
upd(y);//注意
}
int query(Node *x,Node *y)
{
mtop(x);access(y);splay(y);
//if(gtop(y)!=x) return 0;//此题保证x与y连通,不需要
return y->xorx;
}
}
LCT::Node *nd[];
int n,m;
int main()
{
int i,idx,x,y;
scanf("%d%d",&n,&m);
for(i=;i<=n;i++)
{
nd[i]=LCT::getnode();
scanf("%d",&nd[i]->dat);nd[i]->xorx=nd[i]->dat;//注意改xorx
}
for(i=;i<=m;i++)
{
scanf("%d%d%d",&idx,&x,&y);
if(idx==) printf("%d\n",LCT::query(nd[x],nd[y]));
else if(idx==) LCT::link(nd[x],nd[y]);
else if(idx==) LCT::cut(nd[x],nd[y]);
else if(idx==) LCT::splay(nd[x]),nd[x]->dat=y,LCT::upd(nd[x]);
//可能是由于题面和数据的一些奥妙重重的原因,此题即使不splay(nd[x])也可以A掉,但是splay到根之后却能保证改变该点权值只会影响自身的xorx
}
return ;
}

洛谷 P3690 【模板】Link Cut Tree (动态树) || bzoj 3282: 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. 洛谷.3690.[模板]Link Cut Tree(动态树)

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

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

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

  5. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

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

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

  7. 洛谷P3690 Link Cut Tree (模板)

    Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...

  8. 洛谷P3690 【模板】Link Cut Tree (LCT)

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

  9. 洛谷 P3690 Link Cut Tree

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

  10. Link Cut Tree 动态树 小结

    动态树有些类似 树链剖分+并查集 的思想,是用splay维护的 lct的根是动态的,"轻重链"也是动态的,所以并没有真正的轻重链 动态树的操作核心是把你要把 修改/询问/... 等 ...

随机推荐

  1. 手机没Root?你照样可以渗透路由器

    和Metasploit差不多,RouterSploit是一个强大的漏洞利用框架,用于快速识别和利用路由器中的普通漏洞,它还有个亮点,就是可以在绝大多数安卓设备上运行. 如果你想在电脑上运行,可以阅读这 ...

  2. OpenWrt 安装python-sqlite3失败

    https://dev.openwrt.org/ticket/12239 #12239 reopened defect Sqlite3 missing in python 汇报人: dgspai@- ...

  3. OSWorkFlow流程配置文件具体解释

    AbstractWorkflow>> osworkflow中有关工作流流转的全部核心代码都在AbstractWorkflow中.BasicWorkflow就是派生自它,只是这个BasicW ...

  4. awk基本使用方法简单介绍

    之前说过sed, 今天来说awk, 它也是一个文本处理器. 是linux下的一个命令, 比sed更强大. 搞linux开发, 尤其是后台开发, 这个命令差点儿必需要用到. awk这三个字母分别代表其三 ...

  5. hdu1873 看病要排队(结构体优先队列)

    看病要排队 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  6. js获取get传递的值

    <script language="javascript" src="js/jquery-1.9.0.min.js"></script> ...

  7. C#构造方法(函数) C#方法重载 C#字段和属性 MUI实现上拉加载和下拉刷新 SVN常用功能介绍(二) SVN常用功能介绍(一) ASP.NET常用内置对象之——Server sql server——子查询 C#接口 字符串的本质 AJAX原生JavaScript写法

    C#构造方法(函数)   一.概括 1.通常创建一个对象的方法如图: 通过  Student tom = new Student(); 创建tom对象,这种创建实例的形式被称为构造方法. 简述:用来初 ...

  8. ZrcListView

    https://github.com/zarics/ZrcListView

  9. sql server 支持中文繁体和简体

    SET ANSI_PADDING ON  INSERT INTO 表 VALUES (N'中文')

  10. wpa_supplicant介绍【转】

    本文转载自:https://zhuanlan.zhihu.com/p/24246712 一.什么是wpa_spplicant wpa_supplicant本是开源项目源码,被谷歌修改后加入Androi ...