Cod sursa(job #1773772)

Utilizator GandalfTheWhiteGandalf the White GandalfTheWhite Data 8 octombrie 2016 10:53:33
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.25 kb
#include <cstdio>
#include <cmath>
#include <vector>
#define N 100005
using namespace std;
int niv[N<<1],euler[N<<1],viz[N],lg[N<<1],rmq[25][N<<2],n,m,k;
vector <int> g[N];

void read()
{
int i,x;
scanf("%d%d",&n,&m);
for (i=2;i<=n;i++)
   {
   scanf("%d",&x);
   g[x].push_back(i);
   }
}

void dfs(int nod,int nivel)
{
vector <int>::iterator it;
euler[++k]=nod;
niv[k]=nivel;
if (!viz[nod]) viz[nod]=k;
for (it=g[nod].begin();it!=g[nod].end();it++)
    {
    dfs(*it,nivel+1);
    euler[++k]=nod;
    niv[k]=nivel;
    }
}

void Rmq()
{
int i,j,l;
for(i=2; i<=k; ++i)
lg[i]=lg[i >> 1]+1;
for (i=1;i<=k;i++)
rmq[0][i]=i;
for (i=1;(1<<i)<k;++i)
for (j=1;j<=k-(1<<i);++j)
    {
     l=1<<(i-1);
     rmq[i][j]=rmq[i-1][j];
     if (niv[rmq[i-1][j+l]]<niv[rmq[i][j]])
            rmq[i][j]=rmq[i-1][j+l];
    }
}
int lca(int x,int y)
{
int a,b,dif,q,l,sol;
a=viz[x];b=viz[y];
if (a>b) swap(a,b);
dif=b-a+1;
l=lg[dif];
sol=rmq[l][a];
q=dif-(1<<l);
if (niv[sol]>niv[rmq[l][a+q]]) sol=rmq[l][a+q];
return euler[sol];
}
int main()
{
int i,x,y;
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
read();
dfs(1,0);
Rmq();
for (i=1;i<=m;i++)
   {
   scanf("%d%d",&x,&y);
   printf("%d\n",lca(x,y));
   }
}