Cod sursa(job #1801589)

Utilizator ionutpop118Pop Ioan Cristian ionutpop118 Data 9 noiembrie 2016 12:43:05
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int NMAX = 100000;
const int LGMAX = 18;
 
vector <int> fii[NMAX + 5];
int first[NMAX + 5], euler[NMAX + 5], nivel[NMAX + 5], lge;
int rmq[LGMAX + 2][2 * NMAX], lg[2 * NMAX];
 
void dfs(int nod, int lv)
{
    euler[++lge] = nod;
    nivel[lge] = lv;
    first[nod] = lge;
    for (int i = 0; i < fii[nod].size(); ++i)
    {
        dfs(fii[nod][i], lv + 1);
        euler[++lge] = nod;
        nivel[lge] = lv;
    }
}
int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    int n, m, mid, ans, x, y;
 
    scanf("%d %d", &n, &m);
    for (int i = 2; i <= n; ++i)
    {
        scanf("%d", &x);
        fii[x].push_back(i);
    }
    dfs(1, 0);
    for (int i = 2; i <= lge; ++i)
        lg[i] = 1 + lg[i / 2];
    for (int i = 1; i <= lge; ++i)
        rmq[0][i] = i;
    for (int i = 1; i <= lg[lge]; ++i)
        for (int j = 1; j <= lge; ++j)
	{
		rmq[i][j] = rmq[i - 1][j];
            if ((1 << i) <= j && nivel[rmq[i][j]] > nivel[rmq[i - 1][j - (1 << (i - 1))]])
                    rmq[i][j] = rmq[i - 1][j - (1 << (i - 1))];
        }
    for (int i = 1; i <= m; ++i)
    {
        scanf("%d %d", &x, &y);
        x = first[x], y = first[y];
        if (x > y)
            swap(x, y);
        mid = lg[y - x + 1];
        ans = rmq[mid][y];
        if (nivel[ans] > nivel[rmq[mid][x + (1 << mid) - 1]])
            ans = rmq[mid][x + (1 << mid) - 1];
        printf("%d\n", euler[ans]);
    }
 
    return 0;
}