Cod sursa(job #2006803)

Utilizator popabogdanPopa Bogdan Ioan popabogdan Data 31 iulie 2017 19:20:06
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <bits/stdc++.h>

#define Nmax 100005
#define logNmax 20

using namespace std;

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

vector <int> G[Nmax];
int RMQ[logNmax][Nmax];
int first[Nmax];
int E[2 * Nmax], lg[2 * Nmax];
int H[Nmax];
int N, M;
int L;

int query(int le, int ri)
{
    int diff = ri - le + 1;
    int l = lg[diff];
    diff -= 1 << l;
    int ans = RMQ[l][le];
    if(H[ans] > H[RMQ[l][le + diff]])
        ans = RMQ[l][le + diff];
    return ans;
}

void DFS(int node)
{
    E[++L] = node;
    first[node] = L;
    for(auto it : G[node])
    {
        H[it] = 1 + H[node];
        DFS(it);
        E[++L] = node;
    }
}

int main()
{
    fin >> N >> M;
    for(int i = 2; i <= N; i++)
    {
        int x;
        fin >> x;
        G[x].push_back(i);
    }
    DFS(1);
    for(int i = 2; i <= L; i++)
        lg[i] = 1 + lg[i / 2];
    for(int i = 1; i <= L; i++)
        RMQ[0][i] = E[i];
    for(int i = 1; (1 << i) <= L; i++)
        for(int j = 1; j <= L - (1 << i) + 1; j++)
        {
            RMQ[i][j] = RMQ[i - 1][j];
            if(H[RMQ[i][j]] > H[RMQ[i - 1][j + (1 << (i - 1))]])
                RMQ[i][j] = RMQ[i - 1][j + (1 << (i - 1))];
        }
    while(M--)
    {
        int x, y;
        fin >> x >> y;
        x = first[x];
        y = first[y];
        if(x > y)
            swap(x, y);
        fout << query(x, y) << "\n";
    }
    return 0;
}