Cod sursa(job #2241717)

Utilizator IustinPetrariuIustinian Petrariu IustinPetrariu Data 16 septembrie 2018 19:53:25
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#define NMAX 200005
#define nmax 100005
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector< int > G[nmax];
int N,Q,Size;
int lg[NMAX],level[nmax],euler[NMAX],First[nmax];
int Rmq[20][NMAX];
int minimum(int x, int y)
{
    if(level[x] < level[y])return x;
    return y;
}
void DFS(int node)
{
    Size++;
    euler[Size]=node;
    First[node]=Size;
    for(int i = 0 ; i < G[node].size(); i++)
    {
        level[G[node][i]]=level[node]+1;
        DFS(G[node][i]);
        Size++;
        euler[Size]=node;
    }
}
void construct()
{
    lg[1]=0;
    for(int i = 2; i <= Size; i++)
        lg[i]=lg[i/2]+1;

    for(int i = 1; i <= Size; i++)
        Rmq[i][0]=euler[i];

    for(int j = 1; (1<<j) <= Size; j++)
    {
        for(int i = 1; i <= Size-(1<<j)+1; i++)
        {
            Rmq[i][j]=minimum(Rmq[i][j-1],Rmq[i+(1<<(j-1))][j-1]);
        }
    }
}
int LCA(int X, int Y)
{
    X=First[X];
    Y=First[Y];
    if(X>Y) swap(X,Y);
    long int k=lg[Y-X+1];
    return minimum(Rmq[X][k],Rmq[Y-(1<<k)+1][k]);
}
int main()
{
    fin>>N>>Q;
    for(int i = 2; i <= N; i++)
    {
        int w;
        fin>>w;
        G[w].push_back(i);
    }
    DFS(1);
    construct();
    for(;Q;Q--)
    {
        int X,Y;
        fin>>X>>Y;
        fout<<LCA(X,Y)<<'\n';
    }

    return 0;
}