Cod sursa(job #2576638)

Utilizator uvIanisUrsu Ianis Vlad uvIanis Data 6 martie 2020 21:19:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include <bits/stdc++.h>
using namespace std;

const int nmax = 1e5 + 1;

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

int n, m;
vector<vector<int>> arbore(nmax, vector<int>());

vector<int> euler(1, 0);
vector<int> first(nmax);
vector<int> old_index(nmax);

int id = 0;

void dfs_euler(int node, int parent)
{
    int new_index = ++id;
    euler.push_back(new_index);
    first[node] = euler.size() - 1;
    old_index[new_index] = node;

    for(auto& next : arbore[node])
    {
        if(next == parent) continue;

        dfs_euler(next, node);
        euler.push_back(new_index);
    }
}

vector<vector<int>> dp;
vector<int> lg;

int main()
{
    fin >> n >> m;

    for(int i = 1; i < n; ++i)
    {
        int x;
        fin >> x;

        arbore[x].push_back(i + 1);
        arbore[i + 1].push_back(x);
    }

    dfs_euler(1, -1);

    int P = euler.size() - 1;

    lg.resize(P + 1, 0);

    for(int i = 2; i <= P; ++i)
        lg[i] = lg[i >> 1] + 1;

    dp.resize(lg[P] + 1, vector<int>(P + 1));

    for(int i = 1; i <= P; ++i)
        dp[0][i] = euler[i];

    for(int k = 1; k <= lg[P]; ++k)
        for(int i = 1; i + (1<<k)-1 <= P; ++i)
            dp[k][i] = min(dp[k-1][i], dp[k-1][i+(1<<(k-1))]);


    for(int i = 1; i <= m; ++i)
    {
        int x, y;
        fin >> x >> y;

        int fx = first[x];
        int fy = first[y];

        if(fx > fy) swap(fx, fy);

        int len_lg = lg[fy - fx + 1];

        fout << old_index[min(dp[len_lg][fx], dp[len_lg][fy + 1 - (1<<len_lg)])] << '\n';
    }
}