【模板篇】Link Cut Tree模板(指针)
网上一片一片的LCT都是数组写的 orz
用指针写splay的人想用指针写LCT找板子都不好找QAQ
所以能A题了之后自然要来回报社会, 把自己的板子丢上来(然而根本没有人会看)
LCT讲解就省省吧, 我这种蒟蒻也基本讲不清楚, 就扔个板子算了
板子里也没什么注释, 因为函数的命名和世界的主流命名规范是一样的..
那就这样吧.. 贴两道题的板子.
第一个是SDOI2008 Cave洞穴勘测, 一道简单判断连通性的LCT裸题.
三种操作;
- 连x,y 保证连完还是棵树
- 断x,y 保证<x,y>边存在
- 询问x,y是否联通
然而据说用不路径压缩的并查集可过(考场上我估计就写这个了
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=20101;
inline int gn(int a=0,char c=0){
for(;c<'0'||c>'9';c=getchar());
for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a;
}
struct node{
node *fa,*ch[2];
bool rev;
bool getwh();
bool isroot();
void pushdown();
void setch(bool wh,node* child);
}pool[N],*null; int tot;
bool node::getwh(){
return fa->ch[1]==this;
}
bool node::isroot(){
return fa==null||(fa->ch[0]!=this&&fa->ch[1]!=this);
}
void node::pushdown(){
if(null==this||!rev) return;
swap(ch[0],ch[1]);
ch[0]->rev^=1; ch[1]->rev^=1;
rev=0;
}
void node::setch(bool wh,node* child){
pushdown(); ch[wh]=child;
if(null!=child) child->fa=this;
}
void init(){
null=pool; null->rev=0;
null->fa=null->ch[0]=null->ch[1]=null;
}
node* newnode(){
node* x=pool+ ++tot; x->rev=0;
x->ch[0]=x->ch[1]=x->fa=null;
return x;
}
void rotat(node* x){
node *fa=x->fa,*fafa=fa->fa;
if(fafa!=null) fafa->pushdown();
fa->pushdown(); x->pushdown();
int wh=x->getwh();
if(fa->isroot()) x->fa=fa->fa;
else fafa->setch(fa->getwh(),x);
fa->setch(wh,x->ch[wh^1]);
x->setch(wh^1,fa);
}
void fix(node* x){
if(!x->isroot()) fix(x->fa);
x->pushdown();
}
void splay(node* x){
fix(x);
for(;!x->isroot();rotat(x))
if(!x->fa->isroot())
x->getwh()==x->fa->getwh()?rotat(x->fa):rotat(x);
}
node* access(node* x){
node* y=null;
for(;x!=null;x=x->fa){
splay(x); x->ch[1]=y; y=x;
}
return y;
}
void makeroot(node* x){
access(x)->rev^=1;
splay(x);
}
void link(node* x,node* y){
makeroot(x); x->fa=y;
}
void cut(node* x,node* y){
makeroot(x); access(y); splay(y);
x->fa=y->ch[0]=null;
}
node* Find(node* x){
for(access(x),splay(x);x->ch[0]!=null;x->pushdown(),x=x->ch[0]);
return x;
}
int main(){ init();
int n=gn(),m=gn();
for(int i=1;i<=n;++i) newnode();
char opt[123];
for(int i=1;i<=m;++i){
scanf("%s",opt);
int x=gn(),y=gn();
node *X=pool+x,*Y=pool+y;
if(opt[0]=='Q')
puts(Find(X)==Find(Y)?"Yes":"No");
else if(opt[0]=='C')
link(X,Y);
else cut(X,Y);
}
}
然后另一道是luogu的模板题, 这个是带点权的
(如果带边权的话还是化边为点...)
四种操作:
- 查询x,y路径的异或和
- 连x,y 已连通则忽略
- 断x,y 不保证x,y间有边
- 单点修改
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=300020;
inline int gn(int a=0,char c=0){
for(;c<'0'||c>'9';c=getchar());
for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a;
}
struct node{
node *fa,*ch[2];
bool rev; int xum,xx;
bool getwh(){return fa->ch[1]==this;}
bool isroot();
void update(){
xum=ch[0]->xum^ch[1]->xum^xx;
}
void pushdown();
void setch(bool wh,node* child);
}pool[N],*null;
int tot;
bool node::isroot(){
return fa==null||(fa->ch[0]!=this&&fa->ch[1]!=this);
}
void node::pushdown(){
if(this==null||!rev) return;
swap(ch[0],ch[1]);
ch[0]->rev^=1;
ch[1]->rev^=1;
rev=0;
}
void node::setch(bool wh,node* child){
pushdown(); ch[wh]=child;
if(child!=null) child->fa=this;
}
void init(){
null=pool; null->ch[0]=null->ch[1]=null->fa=null; null->rev=0;
}
node* newnode(int val){
node* x=pool+ ++tot; x->xx=val;
x->ch[0]=x->ch[1]=x->fa=null;
x->rev=0; return x;
}
void rotat(node* x){
node *fa=x->fa,*fafa=fa->fa;
if(!fa->isroot()) fafa->pushdown();
fa->pushdown(); x->pushdown();
int wh=x->getwh();
fa->setch(wh,x->ch[wh^1]);
if(fa->isroot()) x->fa=fa->fa;
else fafa->setch(fa->getwh(),x);
x->setch(wh^1,fa);
fa->update(); x->update();
}
void fix(node* x){
if(!x->isroot()) fix(x->fa);
x->pushdown();
}
void splay(node *x){
fix(x);
for(;!x->isroot();rotat(x))
if(!x->fa->isroot())
x->getwh()==x->fa->getwh()?rotat(x->fa):rotat(x);
x->update();
}
node* access(node* x){
node* y=null;
for(;x!=null;x=x->fa){
splay(x);
x->ch[1]=y;
x->update();
y=x;
}
return y;
}
void makeroot(node* x){
access(x)->rev=1; splay(x);
}
void link(node* x,node* y){
makeroot(x);
x->fa=y;
// access(x);
}
void cut(node* x,node* y){
makeroot(x); access(y); splay(y);
x->fa=y->ch[0]=null;
}
node* Find(node* x){
for(access(x),splay(x);x->ch[0]!=null;x->pushdown(),x=x->ch[0]);
return x;
}
void change(node* x,int y){
access(x); splay(x);
x->xx=y; x->update();
}
int query(node* x,node* y){
makeroot(x);
access(y);
splay(y);
return y->xum;
}
int main(){
init();
int n=gn(),m=gn();
for(int i=1;i<=n;++i) newnode(gn());
for(int i=1;i<=m;++i){
int opt=gn(),x=gn(),y=gn();
node *X=pool+x,*Y=opt==3?null:pool+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模板(指针)的更多相关文章
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
- LG3690 【模板】Link Cut Tree (动态树)
题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...
- AC日记——【模板】Link Cut Tree 洛谷 P3690
[模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...
- LG3690 【模板】Link Cut Tree 和 SDOI2008 洞穴勘测
UPD:更新了写法. [模板]Link Cut Tree 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 后接两个整数(x,y),代表询问从x到y ...
- (RE) luogu P3690 【模板】Link Cut Tree
二次联通门 : luogu P3690 [模板]Link Cut Tree 莫名RE第8个点....如果有dalao帮忙查错的话万分感激 #include <cstdio> #includ ...
- LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板
P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...
- 【刷题】洛谷 P3690 【模板】Link Cut Tree (动态树)
题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
- 洛谷P3690 Link Cut Tree (模板)
Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...
- 指针版P3690 【模板】Link Cut Tree (动态树)
题面 传送门 题解 鉴于数组版实在是太慢我用指针版重新写了一遍 代码基本是借鉴了lxl某道关于\(LCT\)的题 //minamoto #include<bits/stdc++.h> #d ...
随机推荐
- pytest-调整测试用例的执行顺序
场景:未考虑按自然顺序执行时,或想变更执行顺序,比如增加 数据的用例要先执行,再执行删除的用例.测试用例默认是按名 称顺序执行的. • 解决: • 安装:pip install pytest-orde ...
- 破解Pycharm 2019.2
参考:https://www.cnblogs.com/pig66/p/11432446.html 1.下载补丁文件 https://pan.baidu.com/s/112tS3XjAENIHaJ-aS ...
- java final关键字详解
final是java中保留关键字,可以声明成员变量.类.方法与本地变量,一旦引用final关键字,将不能再改变这个引用,编译器会检查代码,要是想改变该引用,会报错. final变量? 凡是对成员变量或 ...
- C#5.0 异步编程 Async和Await--异步方法的规范和注意事项
要些异步方法要注意一下几点: 异步方法的返回值有三种: 1.没有任何返回值的void 2.返回一个Task任务的Task,可以获得该异步方法的执行状态 3.返回Task<T> 可以获得异步 ...
- 嵌入式平台 RAM与ROM区分
ROM(Read Only Memory)和RAM(Random Access Memory)指的都是半导体存储器,ROM在系统停止供电的时候仍然可以保持数据,而RAM通常是在掉电之后就丢失数据,典型 ...
- WiFi基础知识
自从只需少量的话费就可以将笔记本.平板电脑连接到互联网,WiFi已成为我们熟知的网络,并无处不在.Wi-Fi对于一些物联网应用十分有用,比如楼宇自动化.内部能源管理.WiFi的重要性对于我们的日常生活 ...
- sql INSERT语句
当我们需要向数据库表中插入一条新记录时,就必须使用INSERT语句. INSERT语句的基本语法是: INSERT INTO <表名> (字段1, 字段2, ...) VALUES (值1 ...
- TFS——更改计算机名称,影响TFS使用
今天把自己电脑的计算机名称改了,打开VS的时候,就提示以下的错误: 报错情况 显示错误:工作区 DADI--20141015Q;SD-SERVER\Administrator 未驻留在此计算机上.如果 ...
- Angularjs 1.3在页面中输出带Html标记的文本
如何Angularjs1.3在页面中输出带Html标记的文本 基于安全考虑,Angularjs不允许用ng-bind或者{{}}的方法输出html文本. 在实际的应用中,比如信息管理系统,用在线编辑器 ...
- [nRF51822 AK II 教程]第一课,开发环境的配置及背景介绍【转】
低功耗蓝牙4.0是全新的技术,并不向下兼容,也就是说它和蓝牙3.0.2.0什么的都不能通信的.另外,蓝牙4.0目前的规范只能做外设和主机(智能手机,电脑等)通讯,也就是说你想用一个单模的蓝牙4.0开发 ...