Cod sursa(job #2137075)

Utilizator andreigeorge08Sandu Ciorba andreigeorge08 Data 20 februarie 2018 16:23:20
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.6 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, m, dimensiune;
vector <int> L[nmax];


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

    for(auto i : L[nod])
    {
        Euler(i, nivel + 1);
        E[++dimensiune] = nod;
        niv[dimensiune] = nivel;
    }
}
void POW2()
{
    p[1] = 0;
    for(int i = 2; i <= dimensiune; i++)
        p[i] = p[i / 2] + 1;
}
void RMQ()
{
    POW2();
    for(int i = 1; i <= dimensiune; i++)
        rmq[0][i] = i;

    int L = p[dimensiune];

    for(int i = 1; i <= L; i++)
        for(int j = 1; j <= dimensiune - (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 Citire()
{
    int x, y;
    fin >> n >> m;
    for(int i = 2; i <= n; i++)
    {
        fin >> x;
        L[x].push_back(i);
    }

    Euler(1, 0);
    RMQ();

    for(int i = 1; i <= m; i++)
    {
        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 << E[min(t, t1)] << "\n";
    }
}
int main()
{
    Citire();
    return 0;
}