Cod sursa(job #1459580)

Utilizator ZenusTudor Costin Razvan Zenus Data 10 iulie 2015 11:49:51
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <bits/stdc++.h>

using namespace std;

const int NSIZE = 100000 + 10;
const int LOG = 17;

vector < int > g[NSIZE];
int d[NSIZE];
int pa[LOG][NSIZE];
int N , i , x , y;

void df(int node , int father)
{
    d[node] = d[father] + 1;
    pa[0][node] = father;

    for (int i = 0 ; i < g[node].size() ; ++i)
    {
        int to = g[node][i];
        if (to == father) continue;

        df(to , node);
    }
}

void DP()
{
    for (int i = 1 ; i <= LOG ; ++i)
    for (int j = 1 ; j <= N ; ++j)
    pa[i][j] = pa[i - 1][pa[i - 1][j]];
}

int kanc(int n,int k)
{
    for (int i = LOG ; i >= 0 ; --i)
    if ( (1 << i) <= k)
    {
        k -= (1 << i);
        n = pa[i][n];
    }

    return n;
}

int lca(int x , int y)
{
    // x is deeper than y
    if (d[x] < d[y]) swap(x , y);

    int q = d[x] - d[y];
    x = kanc(x , q);
    if (x == y) return x;

    //now x is at same level with y

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

    return pa[0][x];
}

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

int Q;
scanf("%d%d" , &N , &Q);

for (i = 2 ; i <= N ; ++i)
{
    scanf("%d" , &x);

    g[i].push_back(x);
    g[x].push_back(i);
}

df(1 , 0);
DP();

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

return 0;
}