Cod sursa(job #2266018)

Utilizator zhm248Mustatea Radu zhm248 Data 22 octombrie 2018 07:47:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.54 kb
#include<cstdio>
#include<vector>
using namespace std;
int l[100001],p[100001][17],t[100001];
vector<int>g[100001];
int lca(int x,int y)
{
    if(l[x]<l[y])
    {
        int aux=x;
        x=y;
        y=aux;
    }
    int log;
    for(log=1;(1LL<<log)<=l[x];++log);
    log--;
    int i;
    for(i=log;i>=0;--i)
    {
        if(l[x]-(1<<i)>=l[y])
            x=p[x][i];
    }
    if(x==y)
        return x;
    for(i=log;i>=0;--i)
    {
        if(p[x][i]!=-1&&p[x][i]!=p[y][i])
        {
            x=p[x][i];
            y=p[y][i];
        }
    }
    return t[x];
}

bool viz[100001];
void dfs(int x)
{
    viz[x]=1;
    for(int j=0;j<(int)g[x].size();++j)
    {
        if(!viz[g[x][j]])
        {
            l[g[x][j]]=l[x]+1;
            dfs(g[x][j]);
        }
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int n,m,i,j,x,y;
    scanf("%d%d",&n,&m);
    for(i=1;i<n;++i)
    {
        scanf("%d",&t[i+1]);
        g[t[i+1]].push_back(i+1);
        g[i+1].push_back(t[i+1]);
    }
    dfs(1);
    for(i=1;i<=n;++i)
    {
        for(j=0;(1<<j)<n;++j)
        {
            p[i][j]=-1;
        }
    }
    for(i=1;i<=n;++i)
    {
        p[i][0]=t[i];
    }
    for(j=1;(1<<j)<n;++j)
    {
        for(i=1;i<=n;++i)
        {
            if(p[i][j-1]!=-1)
                p[i][j]=p[p[i][j-1]][j-1];
        }
    }
    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    return 0;
}