Cod sursa(job #1044965)

Utilizator mvcl3Marian Iacob mvcl3 Data 30 noiembrie 2013 18:00:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.36 kb
//Solutie folosind RMQ

#include <fstream>
#include <vector>
#define in "lca.in"
#define out "lca.out"
#define Max_Size 100009
#define log2M 20

std :: ifstream f(in);
std :: ofstream g(out);

int N, M;
int log2[Max_Size << 1];
int Viz[Max_Size];
int Euler[Max_Size << 1];
int ST[Max_Size << 1][log2M];

std :: vector < int > V[Max_Size];

inline void Read_Data()
{
    f >> N >> M;
    for(int x, i = 2; i <= N; ++i)
    {
        f >> x;
        V[x].push_back(i);
    }
}

void DFS(int node)
{
    Euler[++Euler[0]] = node;

    if(!Viz[node])
        Viz[node] = Euler[0];

    for(auto val : V[node])
    {
        DFS(val);
        Euler[++Euler[0]] = node;
    };
}

inline void Make_ST()
{
    ST[1][0] = Euler[1];
    for(int i = 2; i <= Euler[0]; ++i)
    {
        log2[i] = log2[i >> 1] + 1;
        ST[i][0] = Euler[i];
    }

    for(int j = 1; (1 << j) <= Euler[0]; ++j)
        for(int i = 1; i + (1 << j) - 1 <= Euler[0]; ++i)
            ST[i][j] = std :: min(ST[i][j - 1], ST[i + (1 << (j - 1))][j - 1]);
}

inline void RMQ()
{
    for(int a, b, i = 1; i <= M; ++i)
    {
        f >> a >> b;

        a = Viz[a], b = Viz[b];
        if(a > b)   std :: swap(a, b);

        int k = log2[b - a + 1];

        g << std :: min(ST[a][k], ST[b - (1 << k) + 1][k]) << '\n';
    }
}

int main()
{
    Read_Data();
    DFS(1);
    Make_ST();
    RMQ();

    g.close();
    return 0;
}