Cod sursa(job #2610510)

Utilizator horiacoolNedelcu Horia Alexandru horiacool Data 4 mai 2020 22:43:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.28 kb
#include <iostream>
#include <stdio.h>
#include <vector>
#include <iterator>
using namespace std;
 
#define NMAX 100005
#define logNMAX 20
 
int N, M, i, j, k;
int lg[4*NMAX], d[NMAX], pos[NMAX], euler[logNMAX][4*NMAX];
 
vector <int> v[NMAX];
 
void DF(int xp,int o)
{
   euler[0][++k] = xp;
   pos[xp] = k;
   d[xp] = o;
 
   for (vector<int>::iterator it = v[xp].begin() ; it != v[xp].end() ; ++it)
   {
       DF(*it,o+1);
       euler[0][++k] = xp;
   }
}
 
int Max(int x, int y)
{
    return (d[x] < d[y]) ? x : y;
}
 
void RMQ_build()
{
    lg[1] = 0;
    for(i = 2 ; i <= k ; ++i)
        lg[i] = lg[i/2] + 1;
 
    for(i = 1 ; i <= lg[k] ; ++i)
        for(j = 1 ; j <= k ; ++j)
            euler[i][j] = Max( euler[i-1][j] , euler[i-1][j+(1<<(i-1))] );
}
 
int query(int x, int y)
{
    int l = lg[y-x+1];
 
    return Max( euler[l][x] , euler[l][y-(1<<l)+1] );
}
 
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
 
    scanf("%d %d", &N, &M );
 
    for(i = 1 ; i < N ; ++i)
    {
        scanf("%d", &j);
        v[j].push_back(i+1);
    }
 
    k = 0;
    DF(1,1);
 
    RMQ_build();
 
    int x,y;
    for(i = 0 ; i < M ; ++i)
    {
        scanf("%d %d", &x, &y);
        printf("%d\n", query( min(pos[x],pos[y]) , max(pos[x],pos[y]) ) );
    }
 
    return 0;
}