Cod sursa(job #2370316)

Utilizator ciutanpCiuta Andrei Calin ciutanp Data 6 martie 2019 11:36:21
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.35 kb
#include<bits/stdc++.h>
using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int rmq[10][4*100001];
int H[200001],E[200001],Prim[200001],nr;
int Lg[200001];
int n,m;
vector<int>G[100001];

void DFS(int node,int niv)
{
    H[++nr]=niv;
    E[nr]=node;
    Prim[node]=nr;
    for(auto it:G[node])
    {
        DFS(it,niv+1);
        E[++nr]=node;
        H[nr]=niv;
    }
}
int lca(int x,int y)
{
    int prx=Prim[x];
    int pry=Prim[y];
    if(prx>pry)
        swap(prx,pry);
    int dif=pry-prx+1;
    int pr=Lg[dif];
    int sol=rmq[pr][prx];
    if(E[sol]>E[rmq[pr][prx+dif-(1<<pr)]])
        return E[rmq[pr][prx+dif-(1<<pr)]];
    else
        return E[sol];
}


void Rmq()
{
    for(int i=2;i<=nr;++i)
        Lg[i]=Lg[i>>1]+1;
    for(int i=1;i<=nr;++i)
        rmq[0][i]=i;
    for(int i=1;(1<<i)<nr;++i)
    {
        for(int j=1;j<=nr-(1<<i);++j)
        {
            int pr=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];
            if(H[rmq[i][j]]>H[rmq[i-1][j+pr]])
                rmq[i][j]=rmq[i-1][j+pr];
        }
    }
}


int main()
{
    f>>n>>m;
    for(int i=2;i<=n;++i)
    {
        int x;
        f>>x;
        G[x].push_back(i);
    }
    DFS(1,0);
    Rmq();

    for(int i=1;i<=m;++i)
    {
        int x,y;
        f>>x>>y;
        g<<lca(x,y)<<'\n';
    }
}