Cod sursa(job #1459579)

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

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

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()
{
int Q;
fin >> N >> Q;

for (i = 2 ; i <= N ; ++i)
{
    fin >> x;

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

df(1 , 0);
DP();

for (i = 1 ; i <= Q ; ++i)
{
    fin >> x >> y;
    fout << lca(x , y) << '\n';
}

return 0;
}