Cod sursa(job #2199708)

Utilizator ionanghelinaIonut Anghelina ionanghelina Data 28 aprilie 2018 19:35:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.27 kb
#include<bits/stdc++.h>
#define maxN 100005
using namespace std;
int depth[maxN],anc[maxN][20],n,q,x,y;
vector<int> v[maxN];
inline void dfs(int nod)
{
    for(auto it:v[nod])
    {
        depth[it]=1+depth[nod];
        dfs(it);
    }
}
inline int lca(int x,int y)
{
    if(x==y) return x;
    int lvlx,lvly;
    if(depth[x]<depth[y]) swap(x,y);
    lvlx=depth[x];
    lvly=depth[y];
    for(int i=17;i>=0;i--)
    {
        if((lvlx-(1<<i))>=lvly)
        {
            x=anc[x][i];
            lvlx=depth[x];
        }
    }
    if(x==y) return x;
    for(int i=17;i>=0;i--)
    {
        if(anc[x][i] && anc[x][i]!=anc[y][i])
        {
            x=anc[x][i];
            y=anc[y][i];
        }
    }

    return anc[x][0];
}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    scanf("%d%d",&n,&q);

    for(int i=2;i<=n;i++)
    {
        scanf("%d",&anc[i][0]);
        if(anc[i][0]) v[anc[i][0]].push_back(i);
    }
    depth[1]=1;
    dfs(1);

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=17;j++)
        {
            anc[i][j]=anc[anc[i][j-1]][j-1];
        }
    }

    while(q--)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    return 0;
}