Cod sursa(job #1043483)

Utilizator mlupseLupse-Turpan Mircea mlupse Data 28 noiembrie 2013 17:40:02
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <fstream>
#include <vector>
#define NMax 100005
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> G[NMax];
int N,M,E[2*NMax],L[2*NMax],First[NMax],k,Log2[NMax],RMQ[20][2*NMax];
void Read()
{
    fin>>N>>M;
    for(int i=2;i<=N;i++)
        {
            int x;
            fin>>x;
            G[x].push_back(i);
        }
}
void DFS(int Nod,int Level)
{
    E[++k]=Nod;
    L[k]=Level;
    First[Nod]=k;
    for(unsigned int i=0;i<G[Nod].size();i++)
        {
            int Vecin=G[Nod][i];
            DFS(Vecin,Level+1);
            E[++k]=Nod;
            L[k]=Level;
        }
}

void BuildLog2()
{
    for(int i=2;i<=2*N;i++)
        {
            Log2[i]=Log2[i/2]+1;
        }
}

void BuildRMQ()
{
    N=2*N-1;
    for(int i=1;i<=N;i++)
        RMQ[0][i]=i;
    for(int i=1;(1<<i)<=N;i++)
        for(int j=1;j<=N-(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))];
}


void Solve()
{
    int diff,l,P;
    BuildLog2();
    BuildRMQ();
    while(M--)
    {
        int x,y;
        fin>>x>>y;
        x=First[x];
        y=First[y];
        if(x>y)
            swap(x,y);
        diff=y-x+1;
        l=Log2[diff];
        if(L[RMQ[l][x]]>L[RMQ[l][y-(1<<l)+1]])
            P=RMQ[l][x];
        else
            P=RMQ[l][y-(1<<l)+1];
        fout<<E[P]<<"\n";
    }
}
int main()
{
    Read();
    DFS(1,0);
    Solve();
    return 0;
}