Cod sursa(job #2164612)

Utilizator andreigeorge08Sandu Ciorba andreigeorge08 Data 13 martie 2018 08:45:54
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <bits/stdc++.h>

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

const int nmax = 100005;
int nivel[20 * nmax], E[20 * nmax], rmq[22][4 * nmax], poz[nmax];
int p[nmax], n, m, dim;
vector <int> L[nmax];


void Euler(int nod, int niv)
{
    E[++dim] = nod;
    nivel[dim] = niv;
    poz[nod] = dim;

    for(auto i : L[nod])
    {
        Euler(i, niv + 1);
        E[++dim] = nod;
        nivel[dim] = niv;
    }
}

void RmqB()
{
    p[1] = 0;
    for(int i = 2; i <= dim; i++)
        p[i] = p[i / 2] + 1;

    int L = p[dim];

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

    for(int i = 1; i <= L; i++)
        for(int j = 1; j <= dim - (1 << i) + 1; j++)
        {
            int x = nivel[rmq[i - 1][j]];
            int y = nivel[rmq[i - 1][j + (1 << (i - 1))]];

            if(x < y)
                rmq[i][j] = rmq[i - 1][j];
            else rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }
}

void Citire()
{
    int x, y;
    fin >> n >> m;
    for(int i = 2; i <= n; i++)
    {
        fin >> x;
        L[x].push_back(i);
    }
    Euler(1, 0);
    RmqB();

    while(m--)
    {
        fin >> x  >> y;
        x = poz[x];
        y = poz[y];

        if(x > y)
            swap(x, y);

        int L = p[y - x + 1];
        int t = rmq[L][x];
        int t1 = rmq[L][y - (1 << L) + 1];

        fout << min(E[t], E[t1]) << "\n";
    }
}
int main()
{
    Citire();
    return 0;
}