Cod sursa(job #2348020)

Utilizator MarinPeptenaruMarin Vasile Peptenaru MarinPeptenaru Data 19 februarie 2019 12:07:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.29 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int nx = 100001;
vector < int > v[nx];
int n,m,i,j,poz[3*nx],euler[3*nx],nivel[3*nx],k,lg[3*nx];
int rmq[20][3*nx];
void dfs(int nod, int niv)
{
    euler[++k]=nod;
    nivel[k]=niv;
    poz[nod]=k;
    for(vector < int > :: iterator it = v[nod].begin(); it!=v[nod].end(); it++)
    {
        dfs(*it,niv+1);
        euler[++k]=nod;
        nivel[k]=niv;
    }
}
void build()
{
    for(int i=1; i<=k; i++)
    {
        rmq[0][i]=i;
        if(i>=2)
            lg[i]=lg[i/2]+1;
    }
    for(int i=1; (1<<i)<=k; i++)
        for(int j=1; j+(1<<(i-1))<=k; j++)
            rmq[i][j] = nivel[rmq[i-1][j]]<nivel[rmq[i-1][j+(1<<(i-1))]]? rmq[i-1][j] : rmq[i-1][j+(1<<(i-1))];
}
int lca(int x, int y)
{
    int pozx = poz[x];
    int pozy = poz[y];
    if(pozx>pozy) swap(pozx,pozy);
    int t = pozy - pozx +1;
    t = lg[t];
    return nivel[rmq[t][pozx]]<nivel[rmq[t][pozy-(1<<t)+1]]? euler[rmq[t][pozx]] : euler[rmq[t][pozy - (1<<t) +1]];
}
int main()
{
    in>>n>>m;
    for(i=2; i<=n; i++)
    {
        in>>j;
        v[j].push_back(i);
    }
    dfs(1,1);
    build();
    for(;m;m--)
    {
        in>>i>>j;
        out<<lca(i,j)<<'\n';
    }
    return 0;
}