介绍一种解决最近公共祖先的在线算法,st表,它是建立在线性中的rmq问题之上。

 

代码:

 

 //LCA: DFS+ST(RMQ)

 #include<cstdio>
#include<cctype>
#include<iostream>
using namespace std; const int size=;
int n,m,s,tot;
int first[size],log[size<<],f[size<<][],head[size<<],p[size<<][];
bool vis[size];
struct node1
{
int path,depth;
}a[size*];
struct node2
{
int next,to;
}e[size*]; inline int read()
{
int x=,f=;
char c=getchar();
while (!isdigit(c))
f=c=='-'?-:,c=getchar();
while (isdigit(c))
x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
} inline int write(int x)
{
if (x<)
x=-x;
if (x>)
write(x/);
putchar(x%+);
} inline void add(int from,int to)
{
++tot;
e[tot].to=to;
e[tot].next=head[from];
head[from]=tot;
} inline void logn()
{
int i;
log[]=-;
for (i=;i<=n*+;i++)
log[i]=log[(i>>)]+;
} inline void DFS(int x,int dep)
{
a[++tot].path=x;
a[tot].depth=dep;
first[x]=tot;
vis[x]=true;
for (int i=head[x];i;i=e[i].next)
if (!vis[e[i].to])
{
DFS(e[i].to,dep+);
a[++tot].path=x;
a[tot].depth=dep;
}
} inline void ST()
{
int i,j;
for (i=;i<=tot;i++)
f[i][]=i;
for (j=;j<=log[tot];j++)
for (i=;i+(<<j)<=tot;i++)
{
if (a[f[i][j-]].depth<a[f[i+(<<j-)][j-]].depth)
f[i][j]=f[i][j-];
else
f[i][j]=f[i+(<<j-)][j-];
}
} inline int RMQ(int l,int r)
{
int w=log[r-l+];
return a[f[l][w]].depth<a[f[r-(<<w)+][w]].depth?f[l][w]:f[r-(<<w)+][w];
} inline int LCA(int u,int v)
{
int x=first[u],y=first[v];
if (x>y)
swap(x,y);
return a[RMQ(x,y)].path;
} int main()
{
int i,j,x,y;
n=read();
m=read();
s=read();
logn();
for (i=;i<n;i++)
{
x=read();
y=read();
add(x,y);
add(y,x);
}
tot=;
DFS(s,);
ST();
while (m--)
{
x=read();
y=read();
write(LCA(x,y));
putchar();
}
return ;
}

LCA 算法(一)ST表的更多相关文章

  1. [算法模板]ST表

    [算法模板]ST表 ST表和线段树一样,都能解决RMQ问题(范围最值查询-Range Minimum Query). 我们开一个数组数组\(f[maxn][maxn\log_2]\)来储存数据. 定义 ...

  2. 【算法】ST表

    想学习一下LCA倍增,先 水一个黄题 学一下ST表 ST表 介绍: 这是一个运用倍增思想,通过动态规划来计算区间最值的算法 算法步骤: 求出区间最值 回答询问 求出区间最值: 用f[i][j]来存储从 ...

  3. 算法学习 - ST表 - 稀疏表 - 解决RMQ问题

    2017-08-26 21:44:45 writer:pprp RMQ问题就是区间最大最小值查询问题: 这个SparseTable算法构造一个表,F[i][j] 表示 区间[i, i + 2 ^ j ...

  4. 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块

    题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...

  5. [数据结构与算法-13]ST表

    ST表 主要用来快速查询静态数据区间最大值 思路 数组\(A[i][j]\)存储数列\(\{a_i\}\)中区间\(i \in [i, i+2^j)\)的最大值 查询时只需要查询\(max\{A[i] ...

  6. 算法学习——st表

    st表是一种基于倍增思想的DP. 用于求一个数列中的某个区间的最大/最小值. 用st[i][j]表示从第i个开始往后2^j个点,最大的是多少. 我们令k[i]表示2^i等于多少 那么有转移方程 st[ ...

  7. [poj3264]rmq算法学习(ST表)

    解题关键:rmq模板题,可以用st表,亦可用线段树等数据结构 log10和log2都可,这里用到了对数的换底公式 类似于区间dp,用到了倍增的思想 $F[i][j] = \min (F[i][j - ...

  8. RMQ算法使用ST表实现

    RMQ RMQ (Range Minimum Query),指求区间最小值.普通的求区间最小值的方法是暴力. 对于一个数列: \[ A_1,~ A_2,~ A_3,~ \cdots,~ A_n \] ...

  9. 算法笔记--st表

    概述:用倍增法求区间最值的离线算法,O(nlogn)预处理,O(1)访问. 预处理: 状态:st[i][j]:[i,i+2^j)之间的最值 状态转移:如果j等于0,st[i][j]=a[i] 如果j大 ...

随机推荐

  1. Harbor 学习分享系列1 - centos7.4安装harbor1.5.2

    centos7.4安装harbor1.5.2 前言 本系列分享将Harbor有关教程:分享形式会以百度云盘的形式进行分享,主要教程将以markdown格式进行分享:建议使用markdownpad2这款 ...

  2. abcdocker 的博客

    技术参考总结 abcdocker 的博客 09月 3 篇 20日 Centos7 图形化创建KVM 10日 Nginx 代理Google 进行*** 10日 mac 安装装逼神器cmatrix 08月 ...

  3. UVALive 4877 Non-Decreasing Digits 数位DP

    4877 Non-Decreasing Digits A number is said to be made up ofnon-decreasing digitsif all the digits t ...

  4. 《Linux内核分析》第二周:操作系统是如何工作的

    杨舒雯 20135324 北京电子科技学院 杨舒雯 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1 ...

  5. Java实现模拟登录新浪微博

    毕设题目要使用到新浪微博数据,所以要爬取新浪微博的数据.一般而言,新浪微博的爬虫有两种模式:新浪官方API和模拟登录新浪微博.两种方法的异同点和适用情况就无须赘述了.前辈的文章已经非常多了.写这篇文章 ...

  6. Alpha答辩总结

    [Alpha展示评审表格] 小组序号 小组名称 格式(20%) 内容(20%) PPT(20%) 演讲(20%) 答辩(20%) 总分 1 天机组 15 15 15 15 16 76 2 PMS 16 ...

  7. time since epoch

    C++11 提供了新的获取系统时间的库函数,在获取时间的时候一般常用的是获取time since epoch,下面来看一下如何获取这个时间. #include <iostream> #in ...

  8. “人向猿进阶”之软件工程第三课----WORDCOUNT.EXE统计程序

    ---恢复内容开始--- WC项目要求 这个项目要求写一个命令行程序,模仿已有的wc.exe的功能,并加以扩充,给出某程序设计源语言文件的字符数.单词数和行数.给实现一个统计程序,它能正确统计程序文件 ...

  9. Mysql存储引擎federated

    Mysql数据库存储引擎federated(联盟) 意思就是把两个不同区域的数据库联系起来,以致可以访问在远程数据库的表中的数据,而不是本地的表.->专门针对远程数据库的实现->一般情况下 ...

  10. PHP filemtime() 函数

    定义和用法 filemtime() 函数返回文件内容上次的修改时间. 若成功,则时间以 Unix 时间戳的方式返回.若失败,则返回 false. 语法 filemtime(filename) 参数 描 ...