问题描述
pog在与szh玩游戏,首先pog在纸上画了一棵有根树,这里我们定义1为这棵树的根,然后szh在这棵树中选了若干个点,想让pog帮忙找找这些点的最近公共祖先在哪里,一个点为S的最近公共祖先当且仅当以该点为根的子树包含S中的所有点,且该点深度最大。然而,这个问题是十分困难的,出于szh对pog的爱,他决定只找编号连续的点,即l i  ~r i  。
输入描述
若干组数据(不超过3 组n≥10000 或Q≥10000 )。
每组数据第一行一个整数n(1≤n≤300000) ,表示树的节点个数。
接下来n−1 行,每行两个数A i ,B i  ,表示存在一条边连接这两个节点。
接下来一行一个数Q(1≤Q≤300000) ,表示有Q 组询问。
接下来Q行每行两个数l i ,r i (1≤li≤ri≤n) ,表示询问编号为l i  ~r i  的点的最近公共祖先。
输出描述
对于每组的每个询问,输出一行,表示编号为li~ri的点的最近公共祖先的编号。
输入样例
5
1 2
1 3
3 4
4 5
5
1 2
2 3
3 4
3 5
1 5
输出样例
1
1
3
3
1

思路:

做这题的方法有很多。下面给出2种解法。
1:维护一个跳表,表示编号为i ~i+2 j −1 的LCA,注意在这里求LCA必须用O(1) 的做法才能通过所有数据。可以转换为RMQ,每次查询时只需查询两个数的LCA即可。
2:考虑dfs序,通过在简单的证明可知L~R的LCA为L ~R 中dfs序较小的那个位置与dfs序较大的那个位置的LCA。因此只要通过st表处理L~R最大dfs序与最小dfs序的编号即可。

方法一:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
const int N = 300000+1000;
int Q,n;
int head[N];
struct Edge
{int v,nxt;
}es[N<<1];
int cnt;inline void add_edge(int u,int v)
{es[cnt].v=v;es[cnt].nxt=head[u];head[u]=cnt++;es[cnt].v=u;es[cnt].nxt=head[v];head[v]=cnt++;
}int index;
int vs[N*2],id[N],dep[N];
int lca[N*2][20];
int minn[N][20];
int maxn[N][20];
void dfs(int u,int fa,int h)
{id[u]=++index;vs[index]=u;dep[u]=h;for(int i=head[u];~i;i=es[i].nxt){int v=es[i].v;if(v==fa)continue;dfs(v,u,h+1);vs[++index]=u;}
}int mm[2*N+100];
void ini()
{memset(head,-1,sizeof(head));cnt=index=0;
}
int main()
{mm[0]=-1;for(int i=1;i<=2*N;i++) mm[i]= (((i-1)&i)==0)? mm[i-1]+1:mm[i-1];while(~scanf("%d",&n)){ini();for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);add_edge(u,v);}dfs(1,1,0);for(int i=1;i<=index;i++) lca[i][0]=vs[i];for(int j=1;j<=20;j++)for(int i=1;i+(1<<j)-1<=index;i++){int a=lca[i][j-1],b=lca[i+(1<<(j-1))][j-1];lca[i][j] = dep[a]<dep[b] ? a:b;}for(int i=1;i<=n;i++) minn[i][0]=maxn[i][0]=id[i];for(int j=1;j<=20;j++)for(int i=1;i+(1<<j)-1<=n;i++){minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]);maxn[i][j]=max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]);}scanf("%d",&Q);for(int i=1;i<=Q;i++){int l,r;scanf("%d%d",&l,&r);int k=mm[r-l+1];int L=min(minn[l][k],minn[r-(1<<k)+1][k]);int R=max(maxn[l][k],maxn[r-(1<<k)+1][k]);k=mm[R-L+1];int a=lca[L][k],b=lca[R-(1<<k)+1][k];int ans = dep[a]<dep[b]? a:b;printf("%d\n",ans);}}return 0;
}

方法二:(防止爆栈就换成bfs)
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;const int N = 300000+1000;
const int DEG  = 20;
int Q,n;
int pa[N][20];
int dep[N];
int head[N];
struct Edge
{int v,nxt;
}es[N<<1];
int cnt;
inline void add_edge(int u,int v)
{es[cnt].v=v;es[cnt].nxt=head[u];head[u]=cnt++;es[cnt].v=u;es[cnt].nxt=head[v];head[v]=cnt++;
}
/*
void bfs(int root)
{queue<int>q;dep[root]=0;pa[root][0]=root;q.push(root);while(!q.empty()){int u=q.front();q.pop();for(int i=1;i<DEG;i++)pa[u][i]=pa[pa[u][i-1]][i-1];for(int i=head[u];~i;i=es[i].nxt){int v=es[i].v;if(v==pa[u][0]) continue;pa[v][0]=u;dep[v]=dep[u]+1;q.push(v);}}
}
*/
void dfs(int u,int fa,int h)
{dep[u]=h;pa[u][0]=fa;for(int i=1;i<DEG;i++) pa[u][i]=pa[pa[u][i-1]][i-1];for(int i=head[u];~i;i=es[i].nxt){int v=es[i].v;if(v!=fa) dfs(v,u,h+1);}
}
int dp[N][20];
int LCA(int u,int v)
{if(dep[u]>dep[v]) swap(u,v);for(int det=dep[v]-dep[u],i=0;det;det>>=1,i++)if(det&1) v=pa[v][i];if(u==v) return u;for(int i=DEG-1;i>=0;i--)if(pa[u][i]!=pa[v][i]) v=pa[v][i],u=pa[u][i];return pa[u][0];
}
int mm[N];
void ini()
{memset(head,-1,sizeof(head));cnt=0;
}
int main()
{mm[0]=-1;for(int i=1;i<=N-1;i++)mm[i]= (((i-1)&i)==0)? mm[i-1]+1:mm[i-1];while(~scanf("%d",&n)){ini();for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);add_edge(u,v);}dfs(1,1,0);for(int i=1;i<=n;i++) dp[i][0]=i;for(int j=1;j<=20;j++)for(int i=1;i+(1<<j)-1<=n;i++)dp[i][j]=LCA(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);scanf("%d",&Q);for(int i=1;i<=Q;i++){int l,r;scanf("%d%d",&l,&r);int k=mm[r-l+1];int ans=LCA(dp[l][k],dp[r-(1<<k)+1][k]);printf("%d\n",ans);}}return 0;}
												

HDU 5266 pog loves szh III (LAC)相关推荐

  1. HDU 5266 pog loves szh III(在线倍增LCA+ST)

    Description 给出一棵有n个节点的树,定义1为树根,有q次询问,每次询问区间[a,b]中所有节点的LCA Input 第一行为一整数n表示节点数,之后n-1行每行两个整数a和b表示树的一条边 ...

  2. HDU 5266 pog loves szh III【LCA RMQ】

    B - pog loves szh III 题目:添加链接描述 题意:找出区域l到r的LCA->找l和r的LCA 分析: 链式前向星存树,先用dfs处理结点倍增关系. 然后从循环处理较深结点,直 ...

  3. hdu 5266 pog loves szh III LCA+RMQ

    题意: 给你一棵树,然后询问l~r节点的最近公共祖先(LCA). 思路: 用RMQ维护一段区间的LCA,然后询问时,将两个区间的LCA再求一次LCA即可. code: #pragma comment( ...

  4. hdu 5266 pog loves szh III

    给一棵树,q次询问,每次询问给连续的一个闭区间,问区间所有数的LCA是多少. 做一个dfs序,其中把dfs序最小的点和最大的点做一次LCA求出的点就是答案. #include <bits/std ...

  5. HDU 5265 pog loves szh II(二分)

    题意: 给出n,p,n个数,从中取两个数 a,b , 求出( a + b )% p 的最大值. 解析: 先把每个数%p , 可以发现两个数加起来,要么 < p,要么 ≥ p,然后小于 2p. 那 ...

  6. 【hdu5266】pog loves szh III (LCA+线段树)

    题意:给一颗树,Q次询问L,L+1,L+2...R的LCA 题目传送门 以LCA为权建线段树,直接查询即可 (我用树剖找LCA) 代码: #include<iostream> #inclu ...

  7. hdu 5265 pog loves szh II STL

    pog loves szh II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php? ...

  8. hdu 5265 pog loves szh II

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5265 pog loves szh II Description Pog and Szh are pla ...

  9. hdu 5264 pog loves szh I

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5264 pog loves szh I Description Pog has lots of stri ...

最新文章

  1. mysql2013年8月怎么打出来_2020年8月31日,上周完成了一个查询接口来检查mysql的数据,速度很慢,20200831,从,MySQL,中查,贼...
  2. Exchange 2016 證書無效如何處理?
  3. Windows7 设置 Java环境变量
  4. better-scroll 的介绍
  5. EasyUI Combogrid Bug
  6. javaSE各阶段练习题--数据类型运算符
  7. linux localhost的修改
  8. 企业即时通讯将成为未来企业竞争致胜的关键
  9. 百度 UEditor--自定义上传文件路径及读取文件
  10. ubuntu安装时出现11:资源暂时不可用
  11. dedecms安全提示解决方法
  12. python中求列表的最大最小值,如何在python中获取列表的最小和最大元素
  13. 中文版orgin图像数字化工具_Engauge Digitizer官方版-图形数字化处理软件下载 v10.8 官方版 - 安下载...
  14. 2015年两化融合管理体系贯标试点企业
  15. Unable to instantiate application 解决方法
  16. mzy git学习,撤销修改(二)
  17. NumPy的实用函数整理之percentile
  18. 暴雪中国:《魔兽世界》团队正与国服地区新的潜在发行合作伙伴进行洽谈
  19. android界面美化
  20. 儿童玩具语音智能机器人如何配置联网

热门文章

  1. python如何剪辑音频_用python编程实现音频编辑,利用,剪辑
  2. 电影项目前端页面(ajax,axios)
  3. Vue学习教程1--Vue核心
  4. 数字三角形问题(数塔问题)
  5. 项目总结:凡事预则立,不预则废!
  6. 自学算法,我是如何从小白到拿到大厂offer的
  7. 2021年P气瓶充装考试总结及P气瓶充装操作证考试
  8. MySQL删除数据报错
  9. 数组指针 和 指针数组
  10. JavaSE高级:JVM重点内容探究