Cod sursa(job #2452449)

Utilizator ezioconnorVlad - Gabriel Iftimescu ezioconnor Data 30 august 2019 19:17:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.92 kb
#include <bits/stdc++.h>

using namespace std;

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

int n, m, nr;
int euler[200001], nivel[200001], first[100001], tata[100001], lg[200001], level[100001];
int rmq[20][200001];
vector <int> Muchii[100001];

inline void DFS(int nod)
{
    euler[++nr] = nod;
    nivel[nr] = level[nod];
    if (!first[nod])
        first[nod] = nr;
    for (int i = 0; i < Muchii[nod].size(); ++i)
    {
        DFS(Muchii[nod][i]);
        euler[++nr] = nod;
        nivel[nr] = level[nod];
    }
}

inline void citire()
{
    in >> n >> m;
    for (int i = 2; i <= n; ++i)
    {
        in >> tata[i];
        level[i] = level[tata[i]] + 1;
        Muchii[tata[i]].push_back(i);
    }
}

int main()
{
    int x, y;
    citire();
    DFS(1);
    for (int i = 2; i <= nr; ++i)
        lg[i] = lg[i / 2] + 1;
    for (int i = 1; i <= nr; ++i)
        rmq[0][i] = i;
    for (int l = 1; (1 << l) <= nr; ++l)
    {
        for (int i = 1; i + (1 << l) <= nr; ++i)
        {
            int salt = 1 << (l - 1);
            if (nivel[rmq[l - 1][i]] <= nivel[rmq[l - 1][i + salt]])
                rmq[l][i] = rmq[l - 1][i];
            else
                rmq[l][i] = rmq[l - 1][i + salt];
        }
    }
    /*for (int i = 1; i <= nr; ++i)
        out << euler[i] << " ";
    out << '\n';
    for (int i = 1; i <= nr; ++i)
        out << nivel[i] << " ";
    out << '\n';
    for (int i = 1; i <= n; ++i)
        out << tata[i] << " ";
    out << '\n';*/
    while (m--)
    {
        in >> x >> y;
        if (first[x] > first[y])
            swap(x, y);
        int diff = first[y] - first[x] + 1, l = lg[diff], salt = diff - (1 << l), MIN;
        if (nivel[rmq[l][first[x]]] <= nivel[rmq[l][first[x] + salt]])
            MIN = rmq[l][first[x]];
        else
            MIN = rmq[l][first[x] + salt];
        out << euler[MIN] << '\n';
    }
    return 0;
}