Cod sursa(job #594343)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 7 iunie 2011 10:24:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

vector <unsigned long> G[100005];
unsigned long N, First[100005], Log2[200005], RMQ[20][200010], EulerianF[200010], Level[200010], LEF;

void DFS (unsigned long X, unsigned long L)
{
    unsigned long i;
    EulerianF[++LEF]=X;
    Level[LEF]=X;
    First[X]=LEF;
    for (i=0; i<G[X].size (); ++i)
    {
            DFS (G[X][i], L+1);
            EulerianF[++LEF]=X;;
            Level[LEF]=X;
    }
}

inline unsigned long Min (unsigned long a, unsigned long b)
{
    if (a<b)
    {
        return a;
    }
    return b;
}

inline unsigned long Max (unsigned long a, unsigned long b)
{
    if (a>b)
    {
        return a;
    }
    return b;
}

inline unsigned long MinRMQ (unsigned long a, unsigned long b)
{
    if (Level[a]<Level[b])
    {
        return a;
    }
    return b;
}

void BuildRMQ ()
{
    unsigned long i, j, Putere2, n;
    Log2[1]=0;
    for (i=1; i<=LEF; ++i)
    {
        RMQ[0][i]=i;
        if (i>1)
        {
            Log2[i]=Log2[i/2]+1;
        }
    }
    for (i=1; i<=Log2[LEF]; ++i)
    {
        n=LEF-(1<<i);
        Putere2=1<<(i-1);
        for (j=1; j<=n; j++)
        {
            RMQ[i][j]=MinRMQ (RMQ[i-1][j], RMQ[i-1][j+Putere2]);
        }
    }
}

inline unsigned long Query (unsigned long a, unsigned long b)
{
    unsigned long D, l;
    D=b-a+1;
    l=Log2[D];
    return MinRMQ (RMQ[l][a], RMQ[l][a+D-(1<<l)]);
}

inline unsigned long LCA (unsigned long a, unsigned long b)
{
    unsigned long PozitieEF;
    PozitieEF = Query (Min (First[a], First[b]), Max (First[a], First[b]));
    return EulerianF [PozitieEF];
}

int main()
{
    unsigned long QA, QB, M, i, X;
    fin >> N >> M;
    for (i=2; i<=N; ++i)
    {
        fin >> X;
        G[X].push_back (i);
    }
    DFS (1, 0);
    BuildRMQ ();
    for (; M>0; --M)
    {
        fin >> QA >> QB;
        if (QA==QB)
        {
            fout << QA << "\n";
        }
        else
        {
            fout << LCA (QA, QB) << "\n";
        }
    }
    fin.close ();
    fout.close ();
    return 0;
}