Cod sursa(job #1482271)

Utilizator ZenusTudor Costin Razvan Zenus Data 6 septembrie 2015 19:40:29
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <bits/stdc++.h>

using namespace std;

const int lgmax = 20;
const int nmax = 100000 + 10;

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

#define cin fin
#define cout fout

int n , q , cnt , x , y , i , j;
int L[nmax] , lg[2 * nmax] , d[nmax] , pe[4 * nmax];
int rmq[lgmax][4 * nmax];
vector < int > g[nmax];

void df(int x , int f)
{
    d[x] = d[f] + 1;
    pe[++cnt] = x;
    L[x] = cnt;

    for (auto j = g[x].begin() ; j != g[x].end() ;++j)
    {
        df(*j , x);
        pe[++cnt] = x;
    }
}

int lca(int x , int y)
{
    x = L[x] , y = L[y];
    if (x > y) swap(x , y);

    int k = lg[y - x + 1];
    int wx = rmq[k][x] , wy = rmq[k][y - (1 << k) + 1];

    int res;
    if (d[pe[wx]] > d[pe[wy]]) res = pe[wy];
    else res = pe[wx];

    return res;
}

void dormq()
{
    for (i = 2 ; i <= cnt ; ++i)
    lg[i] = lg[i / 2] + 1;

    for (i = 1 ; i <= cnt ; ++i)
    rmq[0][i] = i;

    for (i = 1 ; (1 << i) <= cnt ; ++i)
    for (j = 1 ; j <= cnt - (1 << i) + 1 ; ++j)
    {
        if (d[pe[rmq[i - 1][j]]] < d[pe[rmq[i - 1][j + (1 << (i - 1))]]])
        rmq[i][j] = rmq[i - 1][j];
        else rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
    }
}

int main()
{

cin >> n >> q;

for (i = 2 ; i <= n ; ++i)
{
    cin >> x;
    g[x].push_back(i);
}

df(1 , 0);
dormq();

for (i = 1 ; i <= q ; ++i)
{
    cin >> x >> y;
    cout << lca(x , y) << '\n';
}

return 0;
}