Cod sursa(job #2833488)

Utilizator puica2018Puica Andrei puica2018 Data 15 ianuarie 2022 11:50:56
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.77 kb
#include <bits/stdc++.h>
#define nmax 200004

using namespace std;

int E[nmax], k; /// nodurile din parcurgerea Euler
int niv[nmax]; /// nivelele nodurilor din parcurgerea Euler
int P[nmax / 2]; /// P[i] = o pozitie a nodului i in E[]
int rmq[20][nmax]; /// range minimum query
vector <int> L[nmax / 2]; /// listele de adiacenta
int len[nmax];
int n;

void DFS(int nod, int nivel)
{
    E[++k] = nod;
    niv[k] = nivel;
    P[nod] = k;
    for(auto i : L[nod])
    {
        DFS(i, nivel + 1);
        E[++k] = nod;
        niv[k] = nivel;
    }
}

int main()
{
    int i, j, Q, x, y, p, sol;
    /// citirea arborelui
    ifstream fin("lca.in");
    ofstream fout("lca.out");

    fin >> n >> Q;
    for (i = 2; i <= n; i++)
    {
        fin >> x;
        L[x].push_back(i);
    }
    /// Construiesc E[] si niv[]
    DFS(1, 0); /// radacina este 1, pe nivelul 0

    /// RMQ
    len[1] = 0;
    for (i = 2; i <= k; ++i)
        len[i] = 1 + len[i / 2];

    /// rmq[i][j] = pozitia minimului de pe intervalul [j..j+2^i-1]
    for (i = 1; i <= k; ++i)
        rmq[0][i] = i;
    for (i = 1; (1 << i) <= k; i++)
        for (j = 1; j - (1 << i) + 1 <= k; j++)
        {
            p = 1 << (i - 1);
            rmq[i][j] = rmq[i - 1][j];
            if (niv[rmq[i - 1][j]] > niv[rmq[i - 1][j + p]])
                rmq[i][j] = rmq[i - 1][j + p];
        }

    /// interogarile
    for (i = 1; i <= Q; ++i)
    {
        fin >> x >> y;
        x = P[x]; y = P[y];
        if (x > y) swap(x, y);
        p = len[y - x + 1];
        sol = rmq[p][x];
        if (niv[sol] > niv[rmq[p][y - (1 << p) + 1]])
            sol = rmq[p][y - (1 << p) + 1];
        fout << E[sol]<<"\n";
    }

    fin.close();
    fout.close();
    return 0;
}