这个博客写得好

 #include <stdio.h>
#include <vector>
#include <string.h>
using namespace std;
const int N = ; /*
lca 转RMQ 询问u和v的lca
我们保存树的遍历序列,那么只要在序列中找到第一次出现u和第一次出现v的位置
然后RMQ该区间深度最小的那个点就是u和v的lca了 那么要保存每个点首次出现的位置
还要保存遍历序列的dep序列,然后RMQ dep序列得到哪一位置的dep最小
然后映射为结点
*/ vector<int> g[N];
int total;
int id[N];
int dep[N];
int ref[N];
int dp[N][];
int pos[N][];
void dfs(int u, int fa, int d)
{
id[u] = ++total;
dep[total] = d;//去
ref[total] = u;
for(int i=;i<g[u].size(); ++i)
{
int v = g[u][i];
if(v==fa)continue;
dfs(v,u,d+);
dep[++total] = d;//回来
ref[total] = u;
} } void init()
{
int n = total;
for(int i=;i<=n;++i)
dp[i][] = i; for(int j=;(<<j)<=n;++j)
{
for(int i=;i+(<<j)-<=n;++i)
{
int a = dp[i][j-];
int b = dp[i+(<<(j-))][j-];
if(dep[a] < dep[b])
dp[i][j] = a;
else
dp[i][j] = b;
}
}
}
int query(int u, int v)
{
if(id[u] > id[v])
swap(u,v);
int L = id[u];
int R = id[v];
int k = ;
while(<<(k+)<=R-L+)k++;
int a = dp[L][k];
int b = dp[R-(<<k)+][k];
if(R[a]<R[b])
{
return ref[a];
}
else
return ref[b];
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=;i<=n;++i)
g[i].clear();
int u,v;
for(int i=;i<n;++i)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
total = ;
dep[] = ;
dfs(,-,);
init();
int m;
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&u,&v);
printf("%d\n",query(u,v));
}
}
return ;
}

lca转RMQ的更多相关文章

  1. LCA和RMQ

    下面写提供几个学习LCA和RMQ的博客,都很通熟易懂 http://dongxicheng.org/structure/lca-rmq/ 这个应该是讲得最好的,且博主还有很多其他文章,可以读读,感觉认 ...

  2. ZOJ 3195 Design the city LCA转RMQ

    题意:给定n个点,下面n-1行 u , v ,dis 表示一条无向边和边权值,这里给了一颗无向树 下面m表示m个询问,问 u v n 三点最短距离 典型的LCA转RMQ #include<std ...

  3. [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]

    参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...

  4. HDU 3078 LCA转RMQ

    题意: n个点 m个询问 下面n个数字表示点权值 n-1行给定一棵树 m个询问 k u v k为0时把u点权值改为v 或者问 u-v的路径上 第k大的数 思路: LCA转RMQ求出 LCA(u,v) ...

  5. 【51NOD1766】树上的最远点对(线段树,LCA,RMQ)

    题意:n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间, 表示点的标号请你求出两个区间内各选一点之间的最大距离,即你需要求出max{dis(i,j) |a<=i<=b,c< ...

  6. LCA与RMQ

    一.什么是LCA? LCA:Least Common Ancestors(最近公共祖先),对于一棵有根树T的任意两个节点u,v,求出LCA(T, u, v),即离跟最远的节点x,使得x同时是u和v的祖 ...

  7. POJ 1986(LCA and RMQ)

    题意:给定一棵树,求任意两点之间的距离. 思路:由于树的特殊性,所以任意两点之间的路径是唯一的.u到v的距离等于dis(u) + dis(v) - 2 * dis(lca(u, v)); 其中dis( ...

  8. HDU 5266 pog loves szh III (线段树+在线LCA转RMQ)

    题目地址:HDU 5266 这题用转RMQ求LCA的方法来做的很easy,仅仅须要找到l-r区间内的dfs序最大的和最小的就能够.那么用线段树或者RMQ维护一下区间最值就能够了.然后就是找dfs序最大 ...

  9. LCA(包含RMQ)

    今天看了RMQ问题 ST的实质是动归 于是我来回顾一下LCA(的各种写法) 因为每次考试发现自己连LCA都写不好 费时 First of all, RMQ板子: [一维] #include<bi ...

随机推荐

  1. NYOJ 1085 数单词 (AC自己主动机模板题)

    数单词 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 为了可以顺利通过英语四六级考试,如今大家每天早上都会早起读英语. LYH本来以为自己在6月份的考试中能够通过六 ...

  2. Highcharts将数据以图表的形式展现

    1.首先将Highcharts插件所需的js跟css样式文件引入项目中,下载地址为:Highcharts.rar 2.在前台页面中添加一个存放图表的容器 <div id="contai ...

  3. 细说在兄弟连搞上PHP的那些事儿

    (据说大家都是这么开头的)又到6月份了,想想自己毕业已经整整一年时间了,这一年可能会是我一生中印象最最深刻的一年,从满怀希望地踏入社会到自信满满 地开始第一份工作再到2个多月后又灰溜溜地辞去工作,回到 ...

  4. open sql 更新数据

    insert语句: 1.插入单行数据有两种方法:wa是一个工作区 insert into dbtab values wa. insert into dbtab from wa. 该语句也可以将数据行插 ...

  5. Qt+gsoap调用WebService

    1.       前言 Qt本身给我们提供了调用WebService的解决方案qsoap,看了一下他的介绍,感觉实在是太弱了,而且又是个新出的东西,所以还是决定不用他.既然使用Qt,那当然是跨平台的解 ...

  6. 积累的VC编程小技巧之属性页

    1.属性页的添加: 创建对话框的类,该类要从CpropertyPage继承:然后在要添加该对话框为属性页的类(头文件)里创建CpropertySheet类的一个对象m_tabsheet和新创建的对话框 ...

  7. Android菜鸟的成长笔记(8)——Intent与Intent Filter(上)

    原文:[置顶] Android菜鸟的成长笔记(8)——Intent与Intent Filter(上) Intent代表了Android应用的启动“意图”,Android应用将会根据Intent来启动指 ...

  8. C++ Primer 学习笔记_76_模板和泛型编程 --模板定义[继续]

    模板和泛型编程 --模板定义[续] 四.模板类型形參 类型形參由keywordclass或 typename后接说明符构成.在模板形參表中,这两个keyword具有同样的含义,都指出后面所接的名字表示 ...

  9. Wayland中的跨进程过程调用浅析

    原文地址:http://blog.csdn.net/jinzhuojun/article/details/40264449 Wayland协议主要提供了Client端应用与Server端Composi ...

  10. Delphi “Invalid floating point operation.”错误的解决方法(使用System单元提供的Set8087CW函数禁用浮点异常)

    这两天用webbrower写东西,有时候打开SSL加密网站时会出现”Invalid floating point operation.”的错误,上网搜了下,把解决方法贴上. 导致原因 在Delphi2 ...