Cod sursa(job #2855564)

Utilizator XyanEusebiu Pusca Xyan Data 22 februarie 2022 16:55:24
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.73 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <set> 
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

const int NMAX = 100010;
int N, M, t[NMAX];
set <int> f[NMAX];
vector <int> euler, levi;
vector <int> rmq[18];
int a[NMAX], p;
void gen(int val, int lv)
{
    euler.push_back(val);
    levi.push_back(lv);
    a[val] = p++;
    for (auto i : f[val]) {
        gen(i, lv + 1);
        euler.push_back(val);
        levi.push_back(lv);
        p++;
    }
}
int grad = 1;
void genrmq()
{
    int j = 1 << grad;
    for (int i = 0; i + j <= p; i++)
        rmq[grad].push_back(levi[rmq[grad - 1][i]] < levi[rmq[grad - 1][i + (j >> 1)]] ? rmq[grad - 1][i] : rmq[grad - 1][i + (j >> 1)]);
    if (1 << ++grad <= p)
        genrmq();
}
int main()
{
    ios_base::sync_with_stdio(false);
    int x, y;
    fin >> N >> M;

    for (int i = 2; i <= N; i++)
    {
        fin >> t[i];
        f[t[i]].insert(i);
    }

    gen(1, 0);

    for (int i = 0; i < euler.size(); i++)
        rmq[0].push_back(i);
    genrmq()
    grad--;
    
    int j, k;
    for (int i = 0; i < M; i++)
    {
        fin >> x >> y;
        if (x == y)
            fout << x << "\n";
        else
        {
            if (a[x] > a[y])
                swap(x, y);
            j = 1 << grad;
            k = grad;

            while (a[y] - a[x] < j && k) {
                j >>= 1;
                k--;
            }
            if (j == a[y] - a[x])
                fout << euler[rmq[k][a[x]]] << "\n";
            else
                fout << euler[(levi[rmq[k][a[x]]] < levi[rmq[k][a[y] - j]] ? rmq[k][a[x]] : rmq[k][a[y] - j])] << "\n";
        }
        
    }
    return 0;
}