Cod sursa(job #1361427)

Utilizator zpaePopescu Andreea zpae Data 25 februarie 2015 21:10:00
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.19 kb
#include <cstdio>
#include <vector>
using namespace std;
#define NR 100002
#define LG 20
int er=1,u[NR],q[NR],lg[NR],e[LG][NR*2];
vector <int> v[NR];

void dfs(int k)
{
    int i;
    if(!q[k])q[k]=er;
    e[0][er++]=k;
    for(i=0;i<v[k].size();i++)
        if(u[v[k][i]]==0)
        {
            u[v[k][i]]=1;
            dfs(v[k][i]);
            e[0][er++]=k;
        }
}

void rmq()
{
    int x,i,j;
    for(i=1;i<=lg[er]+1;i++)
    {
        x=1<<i-1;
        for(j=1;j<=er-2*x+1;j++)
            e[i][j]=min(e[i-1][j],e[i-1][j+x]);
    }
}

int query(int x, int y)
{
    x=q[x];
    y=q[y];
    if(x>y)
        swap(x,y);

    int i=y-x+1;
    int j=i-(1<<lg[i]);
    return min(e[lg[i]][x],e[lg[i]][x+j]);
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int n,m,x,y,i;
    scanf("%d%d",&n,&m);
    for(i=2;i<=n;i++)
    {
        scanf("%d",&x);
        v[x].push_back(i);
    }

    u[i]=1;
    dfs(1);
    er--;

    lg[1]=0;
    for(i=2;i<=er;i++)
        lg[i]=lg[i/2]+1;
    rmq();

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