Cod sursa(job #2146463)

Utilizator andreigeorge08Sandu Ciorba andreigeorge08 Data 27 februarie 2018 23:40:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.48 kb
#include <bits/stdc++.h>

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

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


void Build()
{
    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 = niv[rmq[i - 1][j]];
            int y = niv[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 DFS(int nod, int nivel)
{
    E[++dim] = nod;
    niv[dim] = nivel;
    poz[nod] = dim;

    for(auto i : L[nod])
    {
        DFS(i, nivel + 1);

        E[++dim] = nod;
        niv[dim] = nivel;
    }
}
void Citire()
{
    int x, y;
    fin >> n >> q;

    for(int i = 2; i <= n; i++)
    {
        fin >> x;
        L[x].push_back(i);
    }

    DFS(1, 0);
    Build();

    while(q--)
    {
        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;
}