Cod sursa(job #2082787)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 6 decembrie 2017 19:31:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO

int N, M, I;
int fth[100005], lg2[100005], h[100005];
int itv[100005][2];
int rmq[20][100005];
vector<int> edg[100005];

int minh(int a, int b) { return (h[a] < h[b] ? a : b); }

void DFS(int nod)
{
    itv[nod][0] = ++I;
    rmq[0][I] = nod;
    for(auto nxt: edg[nod])
    {
        h[nxt] = 1 + h[nod];
        DFS(nxt);
    }
    itv[nod][1] = I;
}

int LCA(int x, int y)
{
    if(itv[x][0] <= itv[y][0] && itv[y][1] <= itv[x][1])    return x;
    if(itv[y][0] <= itv[x][0] && itv[x][1] <= itv[y][1])    return y;
    int pa = itv[x][0];
    int pb = itv[y][0];
    if(pa > pb) swap(pa, pb);
    int pw = lg2[pb - pa + 1];
    int nod = minh(rmq[pw][pa], rmq[pw][pb - (1 << pw) + 1]);
    return fth[nod];
}

int main()
{
    #ifdef FILE_IO
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    #endif

    scanf("%d%d", &N, &M);
    for(int i = 2; i <= N; i++)
    {
        scanf("%d", &fth[i]);
        edg[ fth[i] ].push_back(i);
    }

    DFS(1);

    for(int i = 2; i <= N; i++)
    {
        lg2[i] = lg2[i - 1];
        if( (2 << lg2[i]) == i )    lg2[i]++;
    }

    for(int i = 1; (1 << i) <= N; i++)
        for(int j = 1; j + (1 << i) - 1 <= N; j++)
            rmq[i][j] = minh(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);

    for(int i = 1; i <= M; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        int lca = LCA(x, y);
        printf("%d\n", lca);
    }

    return 0;
}