最近公共祖先(LCT)
来一发\(LCT\)求\(LCA\)
\(LCT\)在时间上不占据优势,码量似乎还比树剖,倍增,\(Tarjan\)大一点
但是却是一道\(LCT\)的练手题
对于每一个询问,我们只需要把其中一个点(我们设为a)先\(access\),这样a到根节点的路径就都在一棵\(Splay\)里面了
而且不难发现,有一个很妙的性质:如果两个点不在一条路径上(即\(lca!=a||lca!=b\))那么b点\(access\)以后,b第一次到a到\(root\)的\(Splay\)的上的点即为\(LCA\)
然后我们考虑在将另一个点(我们设为b)与根的路径打通,我们还是一样一直\(Splay\),对于最后一棵\(Splay\)
\(LCA\)即为b第一次到a和rt的那一棵\(Splay\)的位置
那么a,b本来在一个\(Splay\)上呢?
其实也是一样的,我们在分类讨论
1)若\(dep[a]>dep[b]\)那么显然不影响答案,答案就是b点
2)若\(dep[a]<dep[b]\)那么我们在\(access(a)\)时候,a,b就已经不在一颗\(Splay\)里了,所以也不影响答案
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define re register
il int read()
{
re int x = 0, f = 1; re char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x * f;
}
#define get_fa(x) (ch[1][fa[x]] == x)
#define isroot(x) (ch[1][fa[x]] == x || ch[0][fa[x]] == x)
#define updown(x) swap(ch[1][x], ch[0][x]), tag[x] ^= 1
#define rep(i, s, t) for(re int i = s; i <= t; ++ i)
#define maxn 500005
int n, m, s, ch[2][maxn], fa[maxn], st[maxn], top, tag[maxn];
il void pushdown(int x)
{
if(tag[x])
{
if(ch[0][x]) updown(ch[0][x]);
if(ch[1][x]) updown(ch[1][x]);
tag[x] = 0;
}
}
il void rotate(int x)
{
int y = fa[x], z = fa[y], w = get_fa(x), k = get_fa(y);
if(isroot(y)) ch[k][z] = x;
if(ch[w ^ 1][x]) fa[ch[w ^ 1][x]] = y;
fa[x] = z, fa[y] = x;
ch[w][y] = ch[w ^ 1][x], ch[w ^ 1][x] = y;
}
il void Splay(int x)
{
int y = x;
st[++ top] = x;
while(isroot(y)) st[++ top] = y = fa[y];
while(top) pushdown(st[top --]);
while(isroot(x))
{
int y = fa[x];
if(isroot(y)) rotate(get_fa(x) == get_fa(y) ? y : x);
rotate(x);
}
}
il void access(int x)
{
for(re int y = 0; x; x = fa[y = x]) Splay(x), ch[1][x] = y;
}
il void makeroot(int x) {access(x), Splay(x), updown(x);}
il void link(int a, int b) {makeroot(a), fa[a] = b;}
il int query(int a, int b)
{
access(a);
int ans = 0;
for(; b; b = fa[ans = b]) Splay(b), ch[1][b] = ans;
return ans;
}
int main()
{
n = read(), m = read(), s = read();
rep(i, 1, n - 1){int u = read(), v = read(); link(u, v);}
makeroot(s);
while(m --)
{
int a = read(), b = read();
printf("%d\n", query(a, b));
}
return 0;
}
最近公共祖先(LCT)的更多相关文章
- P3379 【模板】最近公共祖先(LCA)(LCT)
\(\color{#0066ff}{ 题目描述 }\) 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. \(\color{#0066ff}{输入格式}\) 第一行包含三个正整数N.M. ...
- LCA最近公共祖先 ST+RMQ在线算法
对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决. 这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...
- 【转】最近公共祖先(LCA)
基本概念 LCA:树上的最近公共祖先,对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. RMQ:区间最小值查询问题.对于长度为n的 ...
- 【并查集】【树】最近公共祖先LCA-Tarjan算法
最近公共祖先LCA 双链BT 如果每个结点都有一个指针指向它的父结点,于是我们可以从任何一个结点出发,得到一个到达树根结点的单向链表.因此这个问题转换为两个单向链表的第一个公共结点(先分别遍历两个链表 ...
- 洛谷P3379 【模板】最近公共祖先(LCA)
P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交 讨论 题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有 ...
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
- 数据结构作业——sights(最短路/最近公共祖先)
sights Description 美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点,由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱的小风姑娘不想走那么 ...
- [最近公共祖先] POJ 3728 The merchant
The merchant Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 4556 Accepted: 1576 Desc ...
- [最近公共祖先] POJ 1330 Nearest Common Ancestors
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 27316 Accept ...
- 图论--最近公共祖先问题(LCA)模板
最近公共祖先问题(LCA)是求一颗树上的某两点距离他们最近的公共祖先节点,由于树的特性,树上两点之间路径是唯一的,所以对于很多处理关于树的路径问题的时候为了得知树两点的间的路径,LCA是几乎最有效的解 ...
随机推荐
- CSS3制作上下跳动动画箭头效果
动画效果如下: 代码如下: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8&q ...
- html 微信video放大后无法返回问题
android video播放视频放大后无法返回,先debug下debugx5.qq.com 发现用的不是X5内核 直接激活 debugmm.qq.com/?forcex5=true 问题解决 ...
- 超级有爱的五款APP共享 可以让你神操作
随着科技的不断发展,手机功能的不断完善,让我们更加依赖手机,不得不说手机给我们带来很多的乐趣和方便. 今天就主要给大家分享五款超级有爱的APP软件,感兴趣的小伙伴已经迫不及待了吧! 荔枝 荔枝是一款声 ...
- iOS:我的学习路径
1.复习C语言(半个月) <C Primer Plus>1-6章 2.学习Objective-C基础语法(一周) 黑马程序员视频 3.直接用Xcode开始APP的实战(半个月) 黑马程序员 ...
- Java:配置环境(Mac)——JDK
1.下载JDK 官网 打开后,直接下载最新版本. 选择dmg文件下载 2.开始安装,一直下一步. 3.打开终端,查询安装路径:/usr/libexec/java_home,复制备用. 4.配置Java ...
- github在README.md中插入图片
例子 
- JS的正则表达式及回文
function palindrome(str) { str = str.replace(/\s/g,"").replace(/[^a-zA-Z0-9]/g,"" ...
- mysql之limit使用
在mysql中,limit的使用方式如下: limit m,n --m:表示从哪一行开始查,n:查询多少条 需要明确的是,m表示取条数的起始位置,而n表示取多少条.例如我查询某个表,获取第一条数据,那 ...
- RIPng(第三组)
一.实验拓扑 2.地址规划 3.实验配置 1)配置各个路由器的端口地址,PC端地址采用自动配置 如本处的PC0,自动获取IPV6地址 2)配置RIP a.现在路由器开启RIP:ipv6 router ...
- MyIsam与InnoDB存储引擎主要区别
MyIsam与InnoDB主要有以下4点大的区别,缓存机制,事务支持,锁定实现,数据物理存储方式(包括索引和数据). 1.缓存机制 myisam 仅仅缓存索引,不会缓存实际数据信息,他会将这一工作交给 ...