洛谷 P3690 【模板】Link Cut Tree (动态树) || bzoj 3282: Tree
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的更多相关文章
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 洛谷P3690 [模板] Link Cut Tree [LCT]
题目传送门 Link Cut Tree 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代 ...
- 洛谷.3690.[模板]Link Cut Tree(动态树)
题目链接 LCT(良心总结) #include <cstdio> #include <cctype> #include <algorithm> #define gc ...
- 【刷题】洛谷 P3690 【模板】Link Cut Tree (动态树)
题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- AC日记——【模板】Link Cut Tree 洛谷 P3690
[模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...
- 洛谷P3690 Link Cut Tree (模板)
Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...
- 洛谷P3690 【模板】Link Cut Tree (LCT)
题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
- 洛谷 P3690 Link Cut Tree
题目背景 动态树 题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
- Link Cut Tree 动态树 小结
动态树有些类似 树链剖分+并查集 的思想,是用splay维护的 lct的根是动态的,"轻重链"也是动态的,所以并没有真正的轻重链 动态树的操作核心是把你要把 修改/询问/... 等 ...
随机推荐
- Qt布局管理器的使用(一)
曾经对Qt的布局管理器掌握的还不清楚,今天特意学习了下.感觉收获还挺大的,特意拿出来和大家分享. 首先.要明确布局管理器的用处,及使我们的界面看起来比較整洁.美化.另外一点就是为了使我们的控件可以更随 ...
- HDU 5303 Delicious Apples (贪心 枚举 好题)
Delicious Apples Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Other ...
- enumerateObjectsUsingBlock 、for 、for(... in ...) 的差别 & 性能測试
for VS for(... in ...) for 的应用范围广基本能够NSArray.NSArray以及C语言的数组等,而for(... in ...)仅限于NSArray.NSArray等 fo ...
- IEnumerator<TItem>和IEnumerator Java 抽象类和普通类、接口的区别——看完你就顿悟了
IEnumerable 其原型至少可以说有15年历史,或者更长,它是通过 IEnumerator 来定义的,而后者中使用装箱的 object 方式来定义,也就是弱类型的.弱类型不但会有性能问题,最主要 ...
- Java使用三种不同循环结构对1+2+3+...+100 求和
▷//第一种求法,使用while结构 /** * @author 9527 * @since 19/6/20 */ public class Gaosi { public static void ma ...
- JavaGUI应用程序打包及数字签名
JavaGUI应用程序部署 JavaGUI程序发布分类: a.Applet:可以嵌入到浏览器中,通过网页的方式展示给用户 b.application :有两种发布方式 :打包成jar包通过bat的方式 ...
- Android多线程更新UI的方式
Android下,对于耗时的操作要放到子线程中,要不然会残生ANR,本次我们就来学习一下Android多线程更新UI的方式. 首先我们来认识一下anr: anr:application not rep ...
- 最新Bootstrap手册
http://www.jqhtml.com/bootstraps-syntaxhigh/index.html
- [读书笔记]流畅的Python(Fluent Python)
<流畅的Python>这本书是图灵科技翻译出版的一本书,作者Luciano Ramalho. 作者从Python的特性角度出发,以Python的数据模型和特殊方法为主线,主要介绍了pyth ...
- Activity动态添加Fragment时遇到的问题
1.Activity动态调用代码 TitleFragement a = new TitleFragement(); getFragmentManager().beginTransacti ...