Cod sursa(job #2017199)

Utilizator cipri321Marin Ciprian cipri321 Data 31 august 2017 15:09:01
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include <fstream>
#include <vector>
#define DIM 1<<18
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");
int n,m;
int E[DIM],L[DIM],H[DIM],nre;
int VIZ[DIM];
vector<int> V[DIM];
int RMQ[18][DIM],LG[DIM];
void euler(int v,int l)
{
    VIZ[v]=1;
    nre++;
    E[nre]=v,L[nre]=l;
    if(!H[v]) H[v]=nre;
    for(int i=0;i<V[v].size();i++)
    {
        int to=V[v][i];
        if(!VIZ[to])
        {
            euler(to,l+1);
            nre++;
            E[nre]=v,L[nre]=l;
        }
    }
}
void initRMQ()
{
    for(int i=1;i<=nre;i++)
        RMQ[0][i]=i;
    for(int i=1;(1<<i)<=nre;i++)
        for(int j=1;j<=nre-(1<<i)+1;j++)
            if(L[RMQ[i-1][j]]<L[RMQ[i-1][j+(1<<(i-1))]])
                RMQ[i][j]=RMQ[i-1][j];
            else
                RMQ[i][j]=RMQ[i-1][j+(1<<(i-1))];
}
int main()
{
    fi>>n>>m;
    for(int i=2;i<=n;i++)
    {
        int p;
        fi>>p;
        V[p].push_back(i);
        V[i].push_back(p);
    }
    euler(1,1);
    initRMQ();
    //precalculam logaritm
    for(int i=2;i<=nre;i++)
        LG[i]=LG[i/2]+1;
    for(int i=1;i<=m;i++)
    {
        int a,b;
        fi>>a>>b;
        a=H[a],b=H[b];
        if(a>b)
            swap(a,b);
        int k=LG[b-a+1];
        if(L[RMQ[k][a]]<L[RMQ[k][b-(1<<k)+1]])
            fo<<E[RMQ[k][a]]<<"\n";
        else
            fo<<E[RMQ[k][b-(1<<k)+1]]<<"\n";
    }
    fi.close();
    fo.close();
    return 0;
}