Cod sursa(job #1628844)

Utilizator radarobertRada Robert Gabriel radarobert Data 4 martie 2016 11:02:06
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <cstdio>
#include <vector>
#include <cmath>
#include <iostream>

using namespace std;

vector<int> g[100002];
int level[100002];
int pos[100002];
int v[200002];
int rmq[21][200002];

void dfs(int node)
{
    v[++v[0]] = node;
    pos[node] = v[0];
    for (unsigned i = 0; i < g[node].size(); i++)
        if (level[g[node][i]] == 0)
        {
            level[g[node][i]] = level[node] + 1;
            dfs(g[node][i]);
            v[++v[0]] = node;
        }
}

int minv(int a, int b)
{
    if (level[a] < level[b])
        return a;
    return b;
}

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

    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 2, x; i <= n; i++)
    {
        scanf("%d", &x);
        g[x].push_back(i);
    }

    level[1] = 1;
    dfs(1);

    for (int i = 1; i <= v[0]; i++)
        rmq[0][i] = v[i];

    cerr << n << ' ' << v[0] << '\n';

    for (int k = 1; k <= log2(v[0]); k++)
        for (int i = 1; i <= v[0];  i++)
            rmq[k][i] = minv(rmq[k-1][i], rmq[k-1][i+(1<<(k-1))]);

    int left, right, l;
    while (m--)
    {
        scanf("%d%d", &left, &right);
        left = pos[left];
        right = pos[right];
        if (left > right)
            swap(left, right);
        right++;
        l = log2(right-left);
        printf("%d\n", minv(rmq[l][left], rmq[l][right-(1<<l)]));
    }

    return 0;
}