Cod sursa(job #2138273)

Utilizator MarinPeptenaruMarin Vasile Peptenaru MarinPeptenaru Data 21 februarie 2018 15:14:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.28 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int nx=100002;
int rmq[20][3*nx],lg[3*nx],e[3*nx],lvl[3*nx],poz[3*nx],k,n,m,i,j;
vector < int > f[nx];
void euler (int nod, int nivel)
{
    e[++k]=nod;
    lvl[k]=nivel;
    poz[nod]=k;
    for(vector < int > :: iterator it=f[nod].begin(); it!=f[nod].end(); it++)
    {
        euler(*it,nivel+1);
        e[++k]=nod;
        lvl[k]=nivel;
    }
}
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<=k-(1<<(i-1)); j++)
            rmq[i][j]=lvl[rmq[i-1][j]]<lvl[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 dif=pozy-pozx+1;
    return lvl[rmq[lg[dif]][pozx]]<lvl[rmq[lg[dif]][pozy-(1<<lg[dif])+1]] ? e[rmq[lg[dif]][pozx]] : e[rmq[lg[dif]][pozy-(1<<lg[dif])+1]];
}
int main()
{
    in>>n>>m;
    for(i=2; i<=n; i++)
    {
        in>>j;
        f[j].push_back(i);
    }
    euler(1,1);
    build();
    for(;m;m--)
    {
        in>>i>>j;
        out<<lca(i,j)<<'\n';
    }
    return 0;
}