Pagini recente » Istoria paginii runda/calcularea_aia/clasament | Cod sursa (job #793325) | Cod sursa (job #1483321) | Cod sursa (job #1297990) | Cod sursa (job #2432918)
#include <bits/stdc++.h>
#define NMAX 100 009
#define LOGMAX 40
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m,cate,x,y;
int level[2*NMAX];
vector <int> g[NMAX];
int euler[2*NMAX];
int ind[NMAX];
int M[2*NMAX][LOGMAX];
bool uz[NMAX];
void citire();
void dfs(int k, int lvl);
void build();
int query();
int main()
{
citire();
dfs(1,1);
build();
for(int i=1;i<=m;i++)
{
fin>>x>>y;
x=ind[x];
y=ind[y];
fout<<query()<<'\n';
}
return 0;
}
void citire()
{
int i,tata;
fin>>n>>m;
for(i=2;i<=n;i++)
{
fin>>tata;
g[tata].push_back(i);
g[i].push_back(tata);
}
}
void dfs(int k, int lvl)
{int i;
euler[++cate]=k;
level[cate]=lvl;
if(!ind[k])
ind[k]=cate;
uz[k]=1;
for(i=0;i<g[k].size();i++)
if(!uz[g[k][i]])
{
dfs(g[k][i],lvl+1);
euler[++cate]=k;
level[cate]=lvl;
}
}
void build()
{
int i,j;
for(i=1;i<=2*n-1;i++)
M[i][0]=i;
for(j=1;(1<<j)<=2*n-1;j++)
for(i=1; i+(1<<j) -1 <= 2*n-1 ;i++)
{
if(level[M[i][j-1]]<level[ M[i+(1<<(j-1))][j-1] ])
M[i][j]=M[i][j-1];
else
M[i][j]=M[i+(1<<(j-1) ) ][j-1];
}
}
int query()
{
int lg;
if(x<y)
swap(x,y);
lg=log2(x-y+1);
if( level[ M[x-(1<<lg)+1][lg] ] < level[ M[y][lg] ])
return euler[ M[x-(1<<lg)+1][lg] ];
return euler[ M[y][lg] ];
}