Cod sursa(job #2285952)

Utilizator ContDeRacistAliniateEBlat ContDeRacist Data 19 noiembrie 2018 16:21:48
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.28 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int N = 1e5 + 7;

vector < int > v[N];
int e[2 * N], poz[N], h[N], log[2 * N];
int rl[N][17], ne(0);

void euler(int nod = 1)
{
    e[++ne] = nod, poz[nod] = ne;
    for (int i : v[nod])
    {
        h[i] = h[nod] + 1;
        euler(i);
        e[++ne] = nod;
    }
}

void premq() {
    log[0] = 1;
    for (int i = 1; (1<<i) < 2 * N; ++i)
        log[i] = log[i / 2] + 1;
    for (int i = 1; i <= ne; ++i)
        rl[i][0] = e[i];
    for (int k = 1; (1<<k) <= ne; ++k)
        for (int i = (1<<k); i <= ne; ++i) {
            rl[i][k] = rl[i][k - 1];
            if (h[rl[i][k - 1]] > h[rl[i - (1<<(k - 1))][k - 1]])
                rl[i][k] = rl[i - (1<<(k - 1))][k - 1];
        }
}

int lca(int x, int y) {
    if (poz[x] > poz[y])
        swap(x, y);
    x = poz[x];
    y = poz[y];
    int ll = log[y - x + 1];
    int a = rl[y][ll];
    int b = rl[x + (1<<ll) - 1][ll];
    if (h[a] > h[b])
        a = b;
    return a;
}

int main()
{
    int n, q, t, x, y;
    cin >> n >> q;
    for (int i = 2; i <= n; ++i) {
        cin >> t;
        v[t].push_back(i);
    }
    euler();
    premq();
    while (q--) {
        cin >> x >> y;
        cout << lca(x, y) << '\n';
    }
    return 0;
}