LCA

描述

给一棵有根树,以及一些询问,每次询问树上的 2 个节点 A、B,求它们的最近公共祖先.

!强制在线!

输入

第一行一个整数 N.

接下来 N 个数,第 i 个数 F i 表示 i 的父亲是 F i. 若 F i = 0,则 i 为树根.

接下来一个整数 M.

接下来 M 行,每行 2 个整数 A、B,询问节点(A xor LastAns)、(Bxor LastAns)的最近公共祖先. 其中 LastAns 为上一个询问的答案,一开始 LastAns = 0.

输出

对每一个询问输出相应的答案.

样例

Sample Input
10
0 1 2 3 2 4 2 5 4 9
10
3 9
2 7
7 8
1 1
0 6
6 11
6 3
10 7
2 15
7 7
Sample Output
3
1
4
5
2
4
2
5
2
5

提示

30%,n,m≤1000

100% n,m≤100,000


既然名字都叫LCA了那当然是求LCA啦然而某些题……

鬼知道是怎么强制在线的。

不管那么多,在线的LCA有2种求法:转换成RMQ,或者倍增跳跳跳。

由于只会倍增的原因在这里选择倍增。

关键操作主要有DFS和lca。

DFS预处理出每个点的深度和倍增数组,

lca中首先让深度最大的点向上跳直到与另一个点平齐,

如果不同的话2个点一起肛肛到你听到为止用倍增数组跳,跳到相等为止。

代码实现算是简单的

代码蒯上

#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gotcha()
{
register int _a=0;bool _b=1;register char _c=getchar();
while(_c<'0' || _c>'9'){if(_c=='-')_b=0;_c=getchar();}
while(_c>='0' && _c<='9')_a=_a*10+_c-48,_c=getchar();
return _b?_a:-_a;
}
const int _ = 100002;
struct edge{int to,ne;edge(){to=ne=0;}}e[_*2];
int he[_]={0},ecnt=0;
void add(int fr,int to)
{e[++ecnt].to=to,e[ecnt].ne=he[fr],he[fr]=ecnt;}
int fa[_][20],dep[_],n;
bool ed[_]={0};
void DFS(int d)
{
ed[d]=1;
int i,j;
for(i=1;i<=18;i++)if(dep[d]>=(1<<i))fa[d][i]=fa[fa[d][i-1]][i-1];
for(i=he[d];i;i=e[i].ne)
if(!ed[j=e[i].to])fa[j][0]=d,dep[j]=dep[d]+1,DFS(j);
}
int finder(int a,int b)
{
if(dep[a]<dep[b])swap(a,b);
int i,cha=dep[a]-dep[b];
for(i=0;i<=18;i++)
{
if(cha & (1<<i))a=fa[a][i];
if(a==b)return a;
}
for(i=18;i>=0;i--)if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
return fa[a][0];
}
int main()
{
register int i,j,t,la=0;
n=gotcha();
for(i=1;i<=n;i++)j=gotcha(),add(i,j),add(j,i);
for(i=1;i<=n;i++)if(!ed[i])DFS(i);
t=gotcha();
while(t--)
{
i=gotcha() xor la,j=gotcha() xor la;
la=finder(i,j),printf("%d\n",la);
}
return 0;
}

倍增 - 强制在线的LCA的更多相关文章

  1. [EOJ439] 强制在线

    Description 见EOJ439 Solution 先考虑不强制在线怎么做. 按询问区间右端点排序,从左往右扫,维护所有后缀的答案. 如果扫到 \(a[i]\),那么让统计个数的 \(cnt[a ...

  2. hihocoder #1236 Scores (15北京赛区网络赛J) (五维偏序,强制在线,bitset+分块)

    链接:http://hihocoder.com/problemset/problem/1236 思路; 有n个五维的向量,给出q个询问,每个询问是一个五维向量,问有多少个向量没有一维比这个向量大.并且 ...

  3. 洛谷 P5105 不强制在线的动态快速排序

    P5105 不强制在线的动态快速排序 题目背景 曦月最近学会了快速排序,但是她很快地想到了,如果要动态地排序,那要怎么办呢? 题目描述 为了研究这个问题,曦月提出了一个十分简单的问题 曦月希望维护一个 ...

  4. luoguP5105 不强制在线的动态快速排序 [官方?]题解 线段树 / set

    不强制在线的动态快速排序 题解 算法一 按照题意模拟 维护一个数组,每次直接往数组后面依次添加\([l, r]\) 每次查询时,暴力地\(sort\)查询即可 复杂度\(O(10^9 * q)\),期 ...

  5. luoguP5105 不强制在线的动态快速排序

    emm 可重集合没用用.直接变成不可重复集合 有若干个区间 每个区间形如[L,R] [L,R]计算的话,就是若干个连续奇数的和.拆位统计1的个数 平衡树维护 加入一个[L,R],把相交的区间合并.之后 ...

  6. [BZOJ 3720][JZYZOJ 2016]gty的妹子树 强制在线 树分块/树套树

    jzyzoj的p2016 先码着,强制在线的树分块或者树套树?关键是我树分块还在入门阶段树套树完全不会啊摔   http://blog.csdn.net/jiangyuze831/article/de ...

  7. SPOJ 10628 Count on a tree(Tarjan离线 | RMQ-ST在线求LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

  8. P5105 不强制在线的动态快速排序

    P5105 不强制在线的动态快速排序 $\bigoplus \limits_{i=2}^n (a_i^2-a_{i-1}^2) = \bigoplus \limits_{i=2}^n (a_i-a_{ ...

  9. POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)

    1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...

随机推荐

  1. #include stdio.h(1)

    #include <stdio.h> int main() { //************一.运算符********** //1.赋值运算符 = ; //赋值运算符表示的是将等号右边的赋 ...

  2. pysnmp使用

    install yum install python-pysnmp yum install python-pyasn1 or pip install pysnmp pip install pyasn1 ...

  3. 在数据绑定控件(如:Repeater)中使用if判断

    方法: target="<%# DataBinder.Eval(Container.DataItem, "数据库字段").ToString() == "t ...

  4. window7防火墙无法更改某些设置,错误代码0×80070422

    原因:这是由于管理工具的服务中的windows防火墙被禁用了. 解决方案:在window7中点击控制面板,然后点击管理工具,在点服务,然后找到windows firewall 然后将其改为自动就就可以 ...

  5. pta 编程题6 树的同构

    其它pta数据结构编程题请参见:pta 题目请参见:树的同构 因题目中左右子树是按照下标给出,因此用数组存放树是更好的方法. 判断两棵树是否同构:用递归的方法.如果当前两个结点都为空,则返回TRUE: ...

  6. OpenCV之CvMat、Mat、IplImage之间相互转换实例(转)

    OpenCV学习之CvMat的用法详解及实例 CvMat是OpenCV比较基础的函数.初学者应该掌握并熟练应用.但是我认为计算机专业学习的方法是,不断的总结并且提炼,同时还要做大量的实践,如编码,才能 ...

  7. 「C基础」C运算符的优先级

    一.运算符的优先级表 C 语言的符号众多,由这些符号又组合成了各种各样的运算符.既然是运算符就一定有其特定的优先级,下表就是C 语言运算符的优先级表: 注:同一优先级的运算符,运算次序由结合方向所决定 ...

  8. Redis(5.0.0)持久化AOF和 RDB 结合源码分析

    主要是挖个坑.候补(代码还没看完..) https://github.com/antirez/redis/tree/5.0 一.Redis保存持久化文件 二.Redis启动加载持久化文件 src/se ...

  9. hdu-1532 Drainage Ditches---最大流模板题

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1532 题目大意: 给出有向图以及边的最大容量,求从1到n的最大流 思路: 传送门:最大流的增广路算法 ...

  10. python_75_json与pickle序列化2

    import pickle def say(name):print('Hi!',name)#用完会释放,要想反序列化,要重新写上该函数 info={ 'name':'Xue Jingjie', 'ag ...