Cod sursa(job #1715229)

Utilizator radiogard1999Dragoi Andrei radiogard1999 Data 10 iunie 2016 10:03:17
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <bits/stdc++.h>

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

vector <int> a[100003];
int e[1000003],niv[1000003],n,m,v[100003],K,poz[100003];
int rmq[22][1000003];

void RMQ()
{
    int i,j,p1,p2;
    for(i=1;i<=K;i++) rmq[0][i]=i;
    for(i=1;(1<<i)<=K;i++)
        for(j=1;j<=K-(1<<i)+1;j++)
        {
            p1=rmq[i-1][j];
            p2=rmq[i-1][j+(1<<(i-1))];
            if(niv[p1]<niv[p2]) rmq[i][j]=p1;
            else rmq[i][j]=p2;
        }
}

void P2()
{
    int i;
    v[1]=0;
    for(i=2;i<=K;i++)
        v[i]=1+v[i/2];
}

void Euler(int x,int nivel)
{
    int i;
    v[x]=1;
    e[++K]=x;
    poz[x]=K;
    niv[K]=nivel;
    for(i=0;i<a[x].size();i++)
        if(v[a[x][i]]==0)
        {
            Euler(a[x][i],nivel+1);
            e[++K]=x;
            niv[K]=nivel;
        }
}

void Citire()
{
    int i,j,x,y;
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>j;
        a[j].push_back(i);
    }
    Euler(1,0);
    P2();
    RMQ();
    int l,p1,p2;
    for(i=1;i<=m;i++)
    {
        fin>>x>>y;
        x=poz[x];
        y=poz[y];
        if(x>y) swap(x,y);
        l=v[y-x+1];
        p1=rmq[l][x];
        p2=rmq[l][y-(1<<l)+1];
        if(niv[p1]<niv[p2]) fout<<e[p1]<<"\n";
        else fout<<e[p2]<<"\n";
    }
}

int main()
{
    Citire();
    return 0;
}