Cod sursa(job #1813622)

Utilizator alexandru822Bosinta Alexandru alexandru822 Data 23 noiembrie 2016 08:48:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 kb
#include <fstream>
#include <vector>

using namespace std;

#define MAX_N 100005
#define MAX_L 20

int K;
int L[MAX_N << 1], H[MAX_N << 1], Lg[MAX_N << 1], First[MAX_N];
int Rmq[MAX_L][MAX_N << 2];

vector<int> G[MAX_N];

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

void dfs(int nod, int level)
{
    H[++K] = nod;
    L[K] = level;
    First[nod] = K;

    for(int t : G[nod])
    {
        dfs(t, level+1);
        H[++K] = nod;
        L[K] = level;
    }
}

int LCA(int x, int y)
{
    int diff, sh, sol, l;
    int a = First[x], b = First[y];
    if(a > b) swap(a, b);
    diff = b - a + 1;
    l = Lg[diff];
    sh = diff - (1 << l);
    sol = Rmq[l][a];
    if(L[sol] > L[Rmq[l][a + sh]])
        sol = Rmq[l][a+sh];
    return H[sol];
}


int main()
{
    int n, m;
    in >> n >> m;
    for(int i=2; i<=n; i++)
    {
        int x;
        in >> x;
        G[x].push_back(i);
    }
    dfs(1,0);

    for(int i = 2; i <= K; ++i)
        Lg[i] = Lg[i >> 1] + 1;
    for(int i = 1; i <= K; ++i)
        Rmq[0][i] = i;

    for(int i = 1; (1 << i) < K; ++i)
        for(int j = 1; j <= K - (1 << i); ++j)
        {
            int l = 1 << (i - 1);

            Rmq[i][j] = Rmq[i-1][j];
            if(L[Rmq[i-1][j + l]] < L[Rmq[i][j]])
                Rmq[i][j] = Rmq[i-1][j + l];
        }
    for(int i=1; i<=m; i++)
    {
        int x, y;
        in >> x >> y;
        out << LCA(x, y) << "\n";
    }
    /*for(int i=0; i<=4; i++)
    {
        for(int j=1; j<=2*n; j++)
            out << H[rmq[i][j]] << " ";
        out << "\n";
    }*/
    return 0;
}