Cod sursa(job #1459912)

Utilizator GinguIonutGinguIonut GinguIonut Data 11 iulie 2015 11:13:02
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.35 kb
#include <fstream>
#include <vector>
#define dimMax 200008
#define dim 100003
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int H[dimMax],Lev[dimMax],k,First[dim],RMQ[20][dimMax],i,j,a,b,lg[dimMax],m,n,x,sol;
vector <int> G[dim];
void dfs(int node, int lvl)
{
    H[++k]=node;
    Lev[k]=lvl;
    First[node]=k;
    for(vector <int>::iterator it=G[node].begin();it!=G[node].end();it++)
    {
        dfs(*it,lvl+1);
        H[++k]=node;
        Lev[k]=lvl;
    }
}
void rmq()
{
    for(i=1;i<=k;i++)
        RMQ[0][i]=i;
    for(i=1;(1 << i)<k;i++)
        for(j=1;j+(1 << i)-1<=k;j++)
        {
            int half= 1 << (i-1);
            RMQ[i][j]=RMQ[i-1][j];
            if(Lev[RMQ[i-1][j+half]]<Lev[RMQ[i][j]])
                RMQ[i][j]=RMQ[i-1][j+half];
        }
}
int lca(int x, int y)
{
    if(x>y)
        swap(x,y);
    int diff=y-x+1;
    int sh=lg[diff];
    sol=RMQ[sh][x];
    if(Lev[RMQ[sh][y-(1 <<sh)+1]]<Lev[sh][RMQ[x]])
        sol=RMQ[sh][y-(1 << sh)+1];
    return H[sol];
}
int main()
{
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>x;
        G[x].push_back(i);
    }
    for(i=2;i<dimMax;i++)
        lg[i]=lg[i >> 1]+1;
    dfs(1,1);
    rmq();
    for(i=1;i<=m;i++)
    {
        fin>>a>>b;
        fout<<lca(First[a],First[b])<<'\n';
    }
    return 0;
}