Cod sursa(job #2572722)

Utilizator ionanghelinaIonut Anghelina ionanghelina Data 5 martie 2020 13:58:11
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.3 kb
#include<bits/stdc++.h>
#define lsb(i) (i&(-i))

using namespace std;

const int maxN=(1e5)+5;
int loga[(1<<20)+5];
int anc[maxN][25];

vector<int> v[maxN];
int depth[maxN];

void dfs(int nod,int fat)
{
    anc[nod][0]=fat;
    for(int i=1;i<=20;i++)
        anc[nod][i]=anc[anc[nod][i-1]][i-1];

    for(auto it:v[nod])
    {
        if(it==fat) continue;
        depth[it]=1+depth[nod];
        dfs(it,nod);
    }
}


inline int query(int x,int y)
{
    if(depth[x]<depth[y]) swap(x,y);

    int d=depth[x]-depth[y];

    while(d)
    {
        int dd=lsb(d);

        x=anc[x][loga[dd]];

        d-=dd;
    }

    for(int i=20;i>=0;i--)
    {
        if(anc[x][i]!=anc[y][i])
        {
            x=anc[x][i];
            y=anc[y][i];
        }
    }

    if(x!=y) x=anc[x][0];

    return x;
}

int n,m,t[maxN],x,y;

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

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

    for(int i=2;i<=n;i++)
    {
        scanf("%d",&t[i]);
        v[t[i]].push_back(i);
    }


    loga[1]=0;

    for(int i=2;i<=(1<<20);i<<=1)
        loga[i]=1+loga[i>>1];

    dfs(1,0);

    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",query(x,y));
    }

    return 0;
}