Cod sursa(job #1385874)

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

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

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();
void DFS(int node, int lvl);
void RangeMinimumQuery();
int LCA(int x, int y);

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

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()
{
    is >> N >> Q;
    for (int i = 2, x; i <= N; ++i)
    {
        is >> x;
        G[x].push_back(i);
    }
};

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;
    }
};