Pagini recente » Cod sursa (job #3255299) | Cod sursa (job #3148294) | Istoria paginii runda/simv_2 | Cod sursa (job #647060) | Cod sursa (job #3263407)
#include <fstream>
#include <cmath>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
/**
*
* RMQ (range minimum query) ;
* | | |
* i j numerele !
* pot sa apara
* de mai multe ori
*
* 10 elem.
*
* 1 5 8 3 9 14 17 7 20 9
*
*
* rmq[n][log n]
*
* i=1,n
* j=1,logn
* 1<<j
*
* rmq[i][0]=v[i]
* rmq[i][j]=min(rmq[i][j-1],rmq[i+2^j])
*
* rmq[i][j]=rez pe interval de la i de lungime 2^j
*
* [x,y] = rmq[x][l]
* rmq[y-l+1][l]
*
* p2[i]-> 2^j<=i, 2^j maxim
*
* p2[i-1] sau p2[i-1]*2
*
* Lowest common ancestor ( LCA ) :
*
* x , y
*
*
*
**/
int n,m,x,y,dif,l;
int kN;
pair<int,int>rmq[200001][20];
int p2[100001];
vector<int>matAdj[100001];
pair<int,int> euler[200001];
int pozitii[100001];
void dfs(int nod,int k){
pozitii[nod]=++kN;
euler[kN] = {k,nod};
for(auto i : matAdj[nod])
{
dfs(i,k+1);
euler[++kN]= {k,nod};
}
}
void create()
{
p2[1]=0;
for(int i=2;i<=2*n;i++)
{
p2[i]=p2[i-1];
if((1<<(p2[i]+1)) <=i)
p2[i]++;
}
dfs(1,0);
n=kN;
for(int i=1;i<=n;i++)
{
rmq[i][0]=euler[i];
}
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i<=n-(1<<j)+1;i++)
{
rmq[i][j]=min(rmq[i][j-1],rmq[i+(1<<(j-1))][j-1]);
}
}
}
int main(){
fin >> n >> m;
for(int i=1;i<n;i++)
{
fin >>x;
matAdj[x].push_back(i+1);
}
create();
for(int q=1;q<=m;q++)
{
fin >> x >> y;
int xX=min(pozitii[x],pozitii[y]);
int yY=max(pozitii[x],pozitii[y]);
l=yY-xX+1;
fout << min(rmq[xX][p2[l]], rmq[yY-(1<<p2[l])+1][p2[l]]).second << '\n';
}
return 0;
}