Pagini recente » Cod sursa (job #1899596) | Cod sursa (job #2455488) | Cod sursa (job #971821) | Cod sursa (job #1442457) | Cod sursa (job #1851414)
#include <iostream>
#include <fstream>
#include <vector>
#define MAX 100005
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int euler[2*MAX],nivel[2*MAX],apar[MAX];
int n,m,e,log[2*MAX];
int rmq[20][2*MAX];
vector <int> G[MAX];
void dfs(int nod, int lvl){/// fac si reprezentarea euler
e++;
euler[e]=nod;
nivel[e]=lvl;
apar[nod]=e;
for(auto it: G[nod]){
dfs(it,lvl+1);
e++;
euler[e]=nod;
nivel[e]=lvl;
}
}
void build_rmq(){///rmq with a twist, am poziti in rmq, dar compar nivelurile elementelor aflate pe acele pozitii
/// in loc de 1<<k<=3 pot folosi k<=log[e]
log[0]=-1;
for(int i=1;i<=e;++i)
log[i]=1+log[i/2];
for(int i=1; i<=e; ++i)
rmq[0][i]=i;
for(int k=1; k<=log[e]; ++k)
for(int i=1; i+(1<<k)-1<=e; ++i){
rmq[k][i]=rmq[k-1][i];
if(nivel[rmq[k-1][i+(1<<(k-1))]] < nivel[rmq[k][i]])
rmq[k][i]=rmq[k-1][i+(1<<(k-1))];
}
}
int query(int x, int y){
x=apar[x];
y=apar[y];
if(x>y)
swap(x,y);
int l=log[y-x+1];
int sol=rmq[l][x];
if(nivel[sol] > nivel[rmq[l][y-(1<<l)+1]])
sol=rmq[l][y-(1<<l)+1];
return euler[sol];
}
int main()
{
fin>>n>>m;
for(int i=2, x; i<=n; ++i){
fin>>x;
G[x].push_back(i);
}
nivel[1]=0;
dfs(1,0);
/* Ca sa vad daca ii reprezentarea euleriana buna
for(int i=1;i<=e;++i)
cout<<euler[i]<<' ';
cout<<'\n';
for(int i=1;i<=e;++i)
cout<<nivel[i]<<' ';*/
build_rmq();
int x,y;
for(int i=1; i<=m; ++i){
fin>>x>>y;
fout<<query(x,y)<<'\n';
}
return 0;
}