Cod sursa(job #890773)

Utilizator tzipleatudTudor Tiplea tzipleatud Data 25 februarie 2013 11:48:54
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.27 kb
#include <fstream>
#include <vector>
#define NM 100010
#define LG 20

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int T[LG][NM];
vector<int> G[NM];
int Level[NM];
int N, M;
int i, j;
int a, b;

void DF (int Node, int Lev)
{
    Level[Node]=Lev;

    for (vector<int>::iterator it=G[Node].begin(); it!=G[Node].end(); ++it)
        DF(*it, Lev+1);
}

int LCA (int A, int B)
{
    if (Level[A]>Level[B])
        swap(A, B);

    int log1, log2, k;

    for (log1=0; (1 << log1)<Level[A]; ++log1);
    for (log2=0; (1 << log2)<Level[B]; ++log2);

    for (k=log2; k>=0; --k)
        if (Level[B]-(1 << k)>=Level[A])
            B=T[k][B];

    if (A==B) return A;

    for (k=log1; k>=0; --k)
        if (T[k][A] && T[k][A]!=T[k][B])
        {
            A=T[k][A];
            B=T[k][B];
        }

    return T[0][A];
}

int main ()
{
    f >> N >> M;

    for (i=2; i<=N; i++)
    {
        f >> T[0][i];
        G[T[0][i]].push_back(i);
    }

    for (j=1; (1 << j)<=N; j++)
        for (i=1; i<=N; i++)
            T[j][i]=T[j-1][T[j-1][i]];

    DF(1, 1);

    for (i=1; i<=M; i++)
    {
        f >> a >> b;
        g << LCA(a, b) << '\n';
    }

    f.close();
    g.close();

    return 0;
}