题目

给出一棵\(n\)个点的树,从1到\(n\)编号,\(m\)次询问\({LCA} _{v\in[L,R]}\)。

\(n,m\le 3\times 10^5​\)

分析

我的做法是直接对LCA进行倍增,即\(f[i][j]\)表示从\(i\)号点开始的\(2^j\)个点的LCA,\(O(n\log ^2 n)\)预处理\(O(\log n)\)查询(分成前后两段,类似RMQ问题中ST表的做法)。

实际上还有复杂度更低的方法。

求一大堆点的共同LCA其实就是求其中dfn序最小和最大的点的LCA。直观的证明如下。取得询问点的中dfn序最小的那个,设为\(x\),另一个点\(v\)点的位置有两种情况:

  • \(v\)在\(x\)的子树内(能满足\(dfn_v>dfn_x\)),那么他们的LCA就是\(x\)
  • \(v\)在\(x\)的子树外,那么它必定在\(x\)的某一个祖先的子树内。这个祖先越往上,\(dfn_v\)就越大。

综上,一堆点的LCA为其中dfn序最小和最大的两点的LCA。

于是这个问题就变成了一个每次得到dfn序的极值点,求一次LCA的了。可以用线段树方便地实现。复杂度为\(O((n+m)\log n)\)。

代码

#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<algorithm>
#define M(x) memset(x,0,sizeof x)
using namespace std;
int read() {int x=0,f=1;char c=getchar();for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;for (;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;
}
const int maxn=3e5+1;
const int maxj=19;
int n,st[maxn][maxj],bin[maxn];
namespace tree {vector<int> g[maxn];int top[maxn],size[maxn],son[maxn],dep[maxn],fat[maxn];void clear(int n) {for (int i=1;i<=n;++i) g[i].clear();M(top),M(size),M(son),M(dep);}void add(int x,int y) {g[x].push_back(y);}int dfs(int x,int fa) {int &sz=size[x]=1,&sn=son[x]=0;dep[x]=dep[fat[x]=fa]+1;for (int v:g[x]) if (v!=fa) {sz+=dfs(v,x);if (size[v]>size[sn]) sn=v;}return sz;}void Top(int x,int fa,int tp) {top[x]=tp;if (son[x]) Top(son[x],x,tp);for (int v:g[x]) if (v!=fa && v!=son[x]) Top(v,x,v);}int lca(int x,int y) {for (;top[x]!=top[y];dep[top[x]]>dep[top[y]]?x=fat[top[x]]:y=fat[top[y]]);return dep[x]<dep[y]?x:y;}
}
int main() {
#ifndef ONLINE_JUDGEfreopen("test.in","r",stdin);
#endifwhile (~scanf("%d",&n)) {tree::clear(n);for (int i=2;i<=n;++i) bin[i]=bin[i>>1]+1;M(st);for (int i=1;i<n;++i) {int x=read(),y=read();tree::add(x,y),tree::add(y,x);}tree::dfs(1,1);tree::Top(1,1,1);for (int i=1;i<=n;++i) st[i][0]=i;for (int j=1;j<maxj;++j) for (int i=1;i<=n;++i) {st[i][j]=st[i][j-1];if ((i+(1<<(j-1)))<=n) st[i][j]=tree::lca(st[i][j],st[i+(1<<(j-1))][j-1]);}int m=read();while (m--) {int l=read(),r=read();int len=r-l+1,d=bin[len];int ans=tree::lca(st[l][d],st[r-(1<<d)+1][d]);printf("%d\n",ans);}}return 0;
}

转载于:https://www.cnblogs.com/owenyu/p/7172213.html

HDU5266-pog loves szh III相关推荐

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

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

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

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

  3. HDU 5266 pog loves szh III (LAC)

    问题描述 pog在与szh玩游戏,首先pog在纸上画了一棵有根树,这里我们定义1为这棵树的根,然后szh在这棵树中选了若干个点,想让pog帮忙找找这些点的最近公共祖先在哪里,一个点为S的最近公共祖先当 ...

  4. hdu 5266 pog loves szh III

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

  5. hdu 5266 pog loves szh III LCA+RMQ

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

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

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

  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. 贪心/二分查找 BestCoder Round #43 1002 pog loves szh II

    题目传送门 1 /* 2 贪心/二分查找:首先对ai%=p,然后sort,这样的话就有序能使用二分查找.贪心的思想是每次找到一个aj使得和为p-1(如果有的话) 3 当然有可能两个数和超过p,那么an ...

  9. 字符串处理 BestCoder Round #43 1001 pog loves szh I

    题目传送门 1 /* 2 字符串处理:是一道水题,但是WA了3次,要注意是没有加'\0'的字符串不要用%s输出,否则在多组测试时输出多余的字符 3 */ 4 #include <cstdio&g ...

  10. BestCoder Round #43 第二题 pog loves szh II

    pog loves szh II  Accepts: 219  Submissions: 834  Time Limit: 4000/2000 MS (Java/Others)  Memory Lim ...

最新文章

  1. 记一次网络共享打印机故障
  2. 在html中横坐标是纵坐标,excel 作图中次横坐标及次纵坐标的调试,以及excel自定义轴标签的步骤方法...
  3. 【Python 必会技巧】获取字典中(多个)最大值(value)的键(key)
  4. Python开发入门与实战14-基于Extjs的界面
  5. 区块链 共识机制研究的重要定理有哪些
  6. 常用电子元件识别图解大全
  7. word文档打印表格时预览时看的到表格打印出来的表格没有上下两根横线?
  8. 树莓派(zero w)——硬件介绍与系统开机
  9. 普通java类注入dao失败_spring mvc 整合mybatis dao接口注入失败
  10. jinjia2 本地渲染文本文件核心代码(可以渲染html,xml,txt等等)
  11. JEP 379:将低暂停时间的垃圾收集器Shenandoah推向生产
  12. 神奇的 SQL 之别样的写法
  13. aptana手动配置python环境_Python学习1:使用Aptana构建Python开发环境
  14. 关于网页背景图怎样自动适应屏幕大小
  15. Javascript中的shift() 、unshift() 和 pop()、push()区别
  16. pygame 单色背景颜色
  17. 开源免费的C/C++网络库 c/c++ sockets library 七剑下天山
  18. android signal 6,android项目运行出现Fatal signal 6 (SIGABRT), code -6 in tid 3
  19. html自动滚动代码,html文字无缝滚动代码
  20. python的论文图表_干货丨史上最全的论文图表基本规范

热门文章

  1. 博客——使用 Redis 实现博客编辑的自动保存草稿功能
  2. C++到底还能做什么? ----感觉说的还是很有道理的,共勉!
  3. 一些IT专业英文缩写(老说这些 是显着自己不low)
  4. 分享50个漂亮的设计师个人作品集网站案例
  5. 天网 20230112
  6. 半色调图像中高频与低频的理解
  7. 【转】经典!python中使用xlrd、xlwt操作excel表格详解
  8. Pomotroid 使用指南:一款高颜值 PC 端番茄时钟
  9. 可怕的乖孩子_你知道乖孩子的一生,有多可怕吗?
  10. 2021-11-01第一节课总结