Cod sursa(job #2308666)

Utilizator TheNextGenerationAyy LMAO TheNextGeneration Data 27 decembrie 2018 15:42:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.41 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int N = 1e5+5;
const int L = 20;
vector<int> v[N];
int euler[2*N],lvl[N],first[N],n,k,rmq[L][2*N],lg[2*N];
void dfs(int x, int l)
{
    euler[++k] = x;
    first[x] = k;
    lvl[x] = l;
    for (auto it: v[x])
        if (!lvl[it])
        {
            dfs(it,l+1);
            euler[++k] = x;
        }
}
void buildDP()
{
    for (int i = 2; i<=k; i++)
        lg[i] = lg[i/2]+1;
    for (int i = 1; i<=k; i++)
        rmq[0][i] = euler[i];
    for (int i = 1; i<=lg[k]; i++)
        for (int j = 1; j<=k-(1<<i); j++)
        {
            rmq[i][j] = rmq[i-1][j];
            if (lvl[rmq[i-1][j+(1<<(i-1))]]<lvl[rmq[i-1][j]])
                rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
        }
}
int query(int x, int y)
{
    x = first[x];
    y = first[y];
    if (x>y)
        swap(x,y);
    int dif = y-x+1, l = lg[dif];
    if (lvl[rmq[l][x]]<lvl[rmq[l][y-(1<<l)+1]])
        return rmq[l][x];
    else
        return rmq[l][y-(1<<l)+1];
}
int main()
{
    int m;
    in >> n >> m;
    for (int i = 2; i<=n; i++)
    {
        int x;
        in >> x;
        v[x].push_back(i);
        v[i].push_back(x);
    }
    lvl[1] = 1;
    dfs(1,1);
    buildDP();
    for (int i = 1; i<=m; i++)
    {
        int x,y;
        in >> x >> y;
        out << query(x,y) << "\n";
    }
}