Cod sursa(job #2789551)

Utilizator NeganAlex Mihalcea Negan Data 27 octombrie 2021 17:25:01
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>

using namespace std;

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

vector <int> V[100005];
int nivel[100005], euler[100005], poz[100005], lll[100005], rmq[20][100005];
int n, m, cnt;
void Citire()
{
    int x, i;
    fin >> n >> m;
    for(i = 2;i <= n;i++)
    {
        fin >> x;
        V[x].push_back(i);
    }
    nivel[1] = 0;
}
void DFS(int nod)
{
    euler[++cnt] = nod;
    poz[nod] = cnt;
    for(auto x : V[nod])
    {
        nivel[x] = nivel[nod] + 1;
        DFS(x);
        euler[++cnt] = nod;
    }
}

void RMQ()
{
    int i, j;
    lll[1] = 0;
    for(i = 2;i <= cnt;i++)
        lll[i] = lll[i / 2] + 1;
    for(i = 1;i <= cnt;i++)
        rmq[0][i] = i;
    int P = lll[cnt];
    for(i = 1;i <= P;i++)
        for(j = 1;j <= cnt - (1 << i) + 1;j++)
        {
            rmq[i][j] = rmq[i - 1][j];
            if(nivel[euler[rmq[i - 1][j]]] > nivel[euler[rmq[i - 1][j + (1 << (i - 1))]]])
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }
}

int Query(int x, int y)
{
    int length = y - x + 1;
    int pp = lll[length], ansnod;
    ansnod = rmq[pp][x];
    if(nivel[euler[ansnod]] > nivel[euler[rmq[y + 1 - (1 << pp)][pp]]])
        ansnod = rmq[pp][y + 1 - (1 << pp)];
    return euler[ansnod];
}
int main()
{
    Citire();
    DFS(1);
    RMQ();
    while(m--)
    {
        int x, y;
        fin >> x >> y;
        int p1 = min(poz[x], poz[y]);
        int p2 = max(poz[x], poz[y]);
        fout << Query(p1, p2) << "\n";
    }
    return 0;
}