Cod sursa(job #2365573)

Utilizator ionanghelinaIonut Anghelina ionanghelina Data 4 martie 2019 14:50:06
Problema Lowest Common Ancestor Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.34 kb
#include<bits/stdc++.h>
#define lsb(i) (i&(-i))

using namespace std;

const int maxN=(1e5)+5;

vector<int> v[maxN];

int depth[maxN],anc[maxN][19];

inline void dfs(int nod)
{
    for(auto it:v[nod])
    {
        depth[it]=1+depth[nod];
        dfs(it);
    }
}
int loga[maxN];

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

    int lvlx=depth[x];
    int lvly=depth[y];
    while(lvlx>lvly)
    {
        int z=lsb(lvlx-lvly);
         x=anc[x][loga[z]];
        lvlx=depth[x];
    }

 //   x=anc[x][0];

    if(x==y) return x;

    for(int step=17;step>=0;step--)
        if(anc[x][step] && anc[x][step]!=anc[y][step])
        {
            x=anc[x][step];
            y=anc[y][step];
        }


    return anc[x][0];
}
int n,q,x,y;


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]);
        v[anc[i][0]].push_back(i);
    }


    depth[1]=1;

    dfs(1);

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

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

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

    return 0;
}