Cod sursa(job #2115956)

Utilizator stefanst77Luca Stefan Ioan stefanst77 Data 27 ianuarie 2018 11:31:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <bits/stdc++.h>

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

int rmq[22][400007];
int E[400007], k;
int niv[400007], poz[100007];
int a[100007], n;
int p[100007];
vector <int> L[100007];

void Euler(int nod, int nivel)
{
    E[++k] = nod; /// vizitez nodul radacina
    niv[k] = nivel;
    poz[nod] = k;
    for (auto w : L[nod])
    {   /// accesam urmasii
        Euler(w, nivel+1);
        E[++k] = nod;
        niv[k] = nivel;
    }
}

int main()
{
    int i, j, q, x, y, N;

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

    Euler(1, 1);

    /// P
    p[1] = 0;
    for (i=2; i<=k; i++)
        p[i] = 1 + p[i/2];

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

    N = p[k];
    for (i = 1; i <= N; i++)
        for (j = 1; j <= k - (1<<i) + 1; j++)
        {
            x = niv[rmq[i-1][j]];
            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))];
        }

    while (q--)
    {
        fin >> x >> y;
        x = poz[x];
        y = poz[y];
        if (x > y) swap(x, y);
        N = p[y - x + 1];
        i = rmq[N][x];
        j = rmq[N][y - (1<<N) + 1];

        if (niv[i] < niv[j]) fout << E[i] << "\n";
        else fout << E[j] << "\n";
    }
    fin.close();
    fout.close();
    return 0;
}