Cod sursa(job #1880484)

Utilizator hegedusPaul Hegedus hegedus Data 15 februarie 2017 19:46:16
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
//LOWEST COMMON ANCESTOR (INFOARENA.RO)
#include <cstdio>
#include <algorithm>
#include <vector>
#define nmax 100001
using namespace std;

int n,q,x,y,k,i,j,l,sol;
int v[2*nmax],rang[nmax],poz[nmax],
    ar[2*nmax][20],av[2*nmax][20];
vector <int> a[nmax];

void dfs(int x, int r)
{
    v[++k]=x; rang[x]=r; poz[x]=k;
    for(unsigned int y=0;y<a[x].size();y++)
        dfs(a[x][y],r+1),
        v[++k]=x;
}

void det_matrice()
{
    for(i=1;i<=k;i++)
        ar[i][0]=rang[v[i]],
        av[i][0]=v[i];
    for(i=k;i;i--)
        for(j=1,l=2;i+l-1<=k;j++,l*=2)
            if(ar[i][j-1]<ar[i+l/2][j-1])
                ar[i][j]=ar[i][j-1],
                av[i][j]=av[i][j-1];
            else
                ar[i][j]=ar[i+l/2][j-1],
                av[i][j]=av[i+l/2][j-1];
}

int lca(int x1, int y1)
{
    int x=min(poz[x1],poz[y1]);
    int y=max(poz[x1],poz[y1]);
    for(j=0,l=1;x+l*2-1<=y;j++,l*=2);
    if(ar[x][j]<ar[y-l+1][j]) return av[x][j];
    else return av[y-l+1][j];
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d %d",&n,&q);
    for(x=2;x<=n;x++)
    {
        scanf("%d",&y);
        a[y].push_back(x);
    }
    dfs(1,1);
    det_matrice();
    while(q)
    {
        scanf("%d %d",&x,&y);
        sol=lca(x,y);
        printf("%d\n",sol);
        q--;
    }
    return 0;
}