Cod sursa(job #1385884)

Utilizator japjappedulapPotra Vlad japjappedulap Data 12 martie 2015 15:32:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <fstream>
#include <vector>
using namespace std;

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

const int BUFFER = 1<<17;
char Pars[BUFFER], *p;

inline int GET();
inline void Check();

const int Nmax = 100001;

int N, Q;
int Euler[Nmax << 1], Depth[Nmax << 1], Ind[Nmax], K;
int RMQ[21][Nmax << 1], Log[Nmax << 1];

vector <int> G[Nmax];

void Read();
inline void DFS(int node, int lvl);
void RangeMinimumQuery();
inline int LCA(int x, int y);

int main()
{
    Read();
    DFS(1, 0);
    RangeMinimumQuery();
    for (int x, y; Q--; os << LCA(x, y) << '\n')
        x = GET(), y = GET();
    is.close();
    os.close();
}

inline int LCA(int x, int y)
{
    int p1, p2;
    p1 = Ind[x], p2 = Ind[y];
    if (p1 > p2) swap(p1, p2);
    int k = Log[p2 - p1];
    return min(Euler[RMQ[k][p1]],
               Euler[RMQ[k][p2 - (1 << k) + 1]]);
};

void RangeMinimumQuery()
{
    for (int i = 1; i <= K; ++i)
        RMQ[0][i] = i;

    for (int i = 2; i <= K; ++i)
        Log[i] = Log[i >> 1] + 1;

    for (int i = 1, k; (1<<i) < K; ++i)
        for (int j = 1; j + (1<<i) <= K+1; ++j)
        {
            k = (1 << (i-1));
            if (Depth[RMQ[i-1][j]] <= Depth[RMQ[i-1][j+k]])
                RMQ[i][j] = RMQ[i-1][j];
            else
                RMQ[i][j] = RMQ[i-1][j+k];
        }
};

void Read()
{
    p = Pars;
    N = GET();
    Q = GET();
    for (int i = 2, x; i <= N; ++i)
    {
        x = GET();
        G[x].push_back(i);
    }
};

inline int GET()
{
    while (*p < '0' || *p > '9') ++p, Check();
    int X = 0;
    while ('0' <= *p && *p <= '9') X = X*10 + (*p - '0'), ++p, Check();
    return X;
};

inline void Check()
{
    if (*p == '\0') is.get(Pars, BUFFER, '\0'), p = Pars;
};

inline void DFS(int node, int lvl)
{
    Ind[node] = ++K;
    Euler[K] = node;
    Depth[K] = lvl;
    for (const int& next : G[node])
    {
        DFS(next, lvl+1);
        Euler[++K] = node;
        Depth[K] = lvl;
    }
};