Cod sursa(job #1522549)

Utilizator EpictetStamatin Cristian Epictet Data 11 noiembrie 2015 20:07:36
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include <fstream>
#include <vector>

#define N_Max 100010

using namespace std;

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

int n, m, k, Euler[N_Max << 1], Level[N_Max << 1], First_Position[N_Max], Log[N_Max << 1], Rmq[20][N_Max << 1];
vector < int > G[N_Max];

void READ_DATA()
{
    fin >> n >> m;
    for (int i = 2, dad; i <= n; i ++)
    {
        fin >> dad;
        G[dad].push_back(i);
    }
}

void DFS(int nod, int adancime)
{
    k ++;
    Euler[k] = nod; /// adaug nodul actual in reprezentarea Euler a arborelui
    Level[k] = adancime; /// adaug adancimea actuala a nodului in reprezentarea Euler a arborelui
    First_Position[nod] = k; /// prima aparitie a nodului actual

    for (vector < int > :: iterator it = G[nod].begin(); it != G[nod].end(); it ++)
    {
        DFS(*it, adancime + 1);

        k ++;
        Euler[k] = nod;
        Level[k] = adancime;
    }
}

void RMQ()
{
    for (int i = 2; i <= k; i ++) Log[i] = Log[i / 2] + 1;
    for (int i = 1; i <= k; i ++) Rmq[0][i] = i;

    for (int i = 1; i <= Log[k]; i ++)
    {
        for (int j = 1; j <= k - (1 << i) + 1; j ++)
        {
            int l = (1 << (i - 1));
            Rmq[i][j] = Rmq[i - 1][j];
            if (Level[Rmq[i - 1][j + l]] < Level[Rmq[i][j]])
            {
                Rmq[i][j] = Rmq[i - 1][j + l];
            }
        }
    }
}

void SOLVE_LCA()
{
    for (int i = 1, x, y, lin, sol; i <= m; i ++)
    {
        fin >> x >> y;
        x = First_Position[x];
        y = First_Position[y];
        if (x > y) swap(x, y);

        lin = Log[y - x + 1];
        sol = Rmq[lin][x];
        if (Level[Rmq[lin][y - (1 << lin) + 1]] < Level[sol])
        {
            sol = Rmq[lin][y - (1 << lin) + 1];
        }
        fout << Euler[sol] << '\n';
    }
}

int main()
{
    READ_DATA();
    DFS(1, 0);
    RMQ();
    SOLVE_LCA();

    return 0;
}