Cod sursa(job #941854)

Utilizator Stefex09Stefan Teodorescu Stefex09 Data 19 aprilie 2013 21:47:48
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.81 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

const int MAXN = 100010 * 2;

int N;
vector <int> Graf[MAXN / 2];
int H[MAXN * 2], Lvl[MAXN * 2], First[MAXN * 2];
int Log[MAXN], RMQ[18][MAXN];
int now;

void DFS (int nod, int lev)
{
    ++ now;
    H[now] = nod;
    Lvl[now] = lev;
    First[nod] = now;

    vector <int> :: iterator it;
    for (it = Graf[nod].begin (); it != Graf[nod].end (); ++ it){
        DFS (*it, lev + 1);
        ++ now;
        H[now] = nod;
        Lvl[now] = lev;
    }

    H[now] = nod;
    Lvl[now] = lev;
}

void Build_Log ()
{
    int i;

    for (i = 2; i < MAXN; i ++)
        Log[i] = Log[i / 2] + 1;
}

void Build_RMQ ()
{
    int i, j, a, b;

    for (i = 1; i <= now; i ++)
        RMQ[0][i] = i;

    for (j = 1; (1 << j) <= now; j ++)
        for (i = 1; i + (1 << j) <= now; i ++){
            a = RMQ[j - 1][i];
            b = RMQ[j - 1][i + (1 << (j - 1))];

            if (Lvl[a] <= Lvl[b])
                RMQ[j][i] = a;
            else
                RMQ[j][i] = b;
        }
}

int LCA (int nod1, int nod2)
{
    nod1 = First[nod1];
    nod2 = First[nod2];

    if (nod2 < nod1)
        swap (nod2, nod1);

    int dif = nod2 - nod1 + 1;
    int log = Log[dif];
    int a, b;
    a = RMQ[log][nod1];
    b = RMQ[log][nod2 - (1 << log) + 1];

    if (Lvl[a] <= Lvl[b])
        return a;
    else
        return b;
}

int main()
{
    int M, i, x, y;

    in >> N >> M;
    for (i = 2; i <= N; i ++){
        in >> x;
        Graf[x].push_back (i);
    }

    DFS (1, 1);
    Build_Log ();
    Build_RMQ ();

    while (M --){
        in >> x >> y;
        out << H[LCA(x, y)] << "\n";
    }

    return 0;
}