Pagini recente » Cod sursa (job #92068) | Cod sursa (job #932466) | Cod sursa (job #53142) | Cod sursa (job #1255781) | Cod sursa (job #1052974)
#include <fstream>
#include <vector>
using namespace std;
vector <int>L[100002];
int euler[200002],nvl[200002],a[21][200002],idx[100002],k,n,m;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
void citire()
{
fin >> n >> m;
for(int i = 2; i <= n; i++)
{
int x;
fin >> x;
L[x].push_back(i);
}
}
void dfs(int v, int niv)
{
euler[++k]=v;
nvl[k]=niv;
idx[v]=k;
for(vector<int>::iterator it=L[v].begin();it!=L[v].end();it++)
{
dfs(*it,niv+1);
euler[++k]=v;
nvl[k]=niv;
}
}
void rmq()
{
for(int i=1;i<=k;i++)
a[0][i]=i;
int di=(1<<1);
for(int i=1;di<=k;)
{
for(int j=1;j+di-1<=k;j++)
{if(nvl[a[i-1][j]]<nvl[a[i-1][j+(1<<(i-1))]])
a[i][j]=a[i-1][j];
else
a[i][j]=a[i-1][j+(1<<(i-1))];
}
i++;
di=(1<<i);
}
}
int lca(int x, int y)
{
int diff, l, sol, sh;
int aa = idx[x], bb = idx[y];
if(aa > bb)
swap(aa, bb);
int k=0;
while((1<<k)<=bb-aa)k++;
if(k>0)k--;
if(nvl[a[k][aa]]<nvl[a[k][bb-(1<<k)+1]])
return euler[a[k][aa]];
else
return euler[a[k][bb-(1<<k)+1]];
}
int main()
{
citire();
dfs(1,1);
rmq();
for(int i=1;i<=m;i++)
{
int x, y;
fin >> x >> y;
fout << lca(x, y) << "\n";
}
return 0;
}