Cod sursa(job #2733121)

Utilizator grigorut_octavianGrigorut Dominic Octavian grigorut_octavian Data 29 martie 2021 22:33:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.4 kb
#include <iostream>
#include <vector>
#include <fstream>

#define MAX 100005

using namespace std;

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

int rmq[20][4*MAX];
int l[2*MAX],h[2*MAX],fr[MAX],lg[2*MAX];
int n,m,k;

vector<int > v[MAX];

void read()
{
    fin>>n>>m;
    for(int i=1;i<n;i++)
    {
        int x;
        fin>>x;
        v[x].push_back(i+1);
    }
}

void dfs(int nod , int niv)
{
    h[++k]=nod;
    l[k]=niv;
    fr[nod]=k;
    for(size_t i=0;i<v[nod].size();i++)
    {
        dfs(v[nod][i],niv+1);
        h[++k]=nod;
        l[k]=niv;
    }
}

void RMQ()
{
    for(int i=2;i<=k;i++)
        lg[i]=lg[i/2]+1;
    for(int i=1;i<=k;i++)
        rmq[0][i]=i;
    for(int i=1; (1 << i) < k;i++)
    {
        for(int j=1;j <= k- (1 << i);j++)
        {
            int le=(1<<(i-1));
            rmq[i][j]=rmq[i-1][j];
            if(l[rmq[i-1][j+le]]<l[rmq[i][j]])
                rmq[i][j]=rmq[i-1][j+le];
        }
    }
}

int lca(int x,int y)
{
    int a=fr[x],b=fr[y];
    if(a > b) swap(a, b);
    int dif=b-a+1;
    int z=lg[dif];
    int sol=rmq[z][a];
    int t=dif-(1<<z);
    if(l[sol]>l[rmq[z][a+t]])
        sol=rmq[z][a+t];
    return h[sol];
}

int main()
{
    int x,y;
   read();

   dfs(1,0);
   RMQ();
   while(m)
   {
       m--;

       fin>>x>>y;
       fout<<lca(x,y)<<'\n';
   }
    return 0;
}