Cod sursa(job #900272)

Utilizator dtoniucDaniel Toniuc dtoniuc Data 28 februarie 2013 18:48:45
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.26 kb
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100010
#define LMAX 20
using namespace std;

vector<int>G[NMAX];
int n,m,H[2*NMAX],F[NMAX],L[2*NMAX],Lg[2*NMAX],K;
int RMQ[LMAX][NMAX/2];

void dfs(int nod,int lvl)
{
    H[++K]=nod;
    L[K]=lvl;
    F[nod]=K;

    for(int i=0;i<G[nod].size();i++)
    {
        dfs(G[nod][i],lvl+1);
        H[++K]=nod;
        L[K]=lvl;
    }
}

int rmq()
{
    for(int i=2;i<=K;i++)
        Lg[i]=Lg[i/2]+1;
    for(int i=1;i<=K;i++)
        RMQ[0][i]=i;

    for(int i=1;(1<<i)<K;++i)
        for(int j=1;j<=K-(1<<i);j++)
        {
            int l=1<<(i-1);

            RMQ[i][j]=(L[RMQ[i-1][j]]<L[RMQ[i-1][j+l]] ? RMQ[i-1][j]:RMQ[i-1][j+l]);
        }
}

int lca(int x,int y)
{
    int a=F[x],b=F[y];
    if(a>b) swap(a,b);
    int l=Lg[b-a+1];
    int sol=(L[RMQ[l][a]]<L[RMQ[l][b-(1<<l)+1]] ? RMQ[l][a]:RMQ[l][b-(1<<l)+1]);
    return H[sol];
}
int main()
{
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    fin>>n>>m;
    int x,y;
    for(int i=2;i<=n;i++)
    {
        fin>>x;
        G[x].push_back(i);
    }
    dfs(1,0);
    rmq();

    for(int i=1;i<=m;i++)
    {
        fin>>x>>y;
        fout<<lca(x,y)<<'\n';
    }
    return 0;
}