Cod sursa(job #1600451)

Utilizator florin.elfusFlorin Elfus florin.elfus Data 15 februarie 2016 00:54:38
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <bits/stdc++.h>

using namespace std;

vector <int> G[100100];

struct LCA {
    int nod;
    int height;
} E[2 * 100100], A[4 * 100100];

int cnt;
bool vis[100100];
int first[100100];

void dfs(int nod, int h) {
    vis[nod] = 1;
    E[cnt].nod = nod;
    E[cnt].height = h;
    first[nod] = cnt;
    ++cnt;
    vector <int> :: iterator it;
    for (it = G[nod].begin(); it != G[nod].end(); ++it)
        if (!vis[*it]) {
            dfs(*it, h + 1);
            E[cnt].nod = nod;
            E[cnt].height = h;
            ++cnt;
        }
}

inline LCA combine(LCA xx, LCA yy) {
    LCA foo;
    if (xx.height < yy.height)
        foo = xx;
    else
        foo = yy;
    return foo;
}

int query(int nod1, int nod2) {
    LCA res;
    res.height = numeric_limits <int> :: max();
    while (nod1 < nod2) {
        if (nod1 % 2) {
            res = combine(res, A[nod1]);
            ++nod1;
        }
        if (nod2 % 2) {
            --nod2;
            res = combine(res, A[nod2]);
        }
        nod1 /= 2;
        nod2 /= 2;
    }
    return res.nod;
}

int main() {
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 2; i <= n; ++i) {
        int d;
        scanf("%d", &d);
        G[d].push_back(i);
    }
    dfs(1, 0);
    for (int i = 0; i < cnt; ++i)
        A[i + cnt] = E[i];
    for (int i = cnt - 1; i >= 1; --i)
        A[i] = combine(A[2 * i], A[2 * i + 1]);
    while (m--) {
        int xx, yy;
        scanf("%d%d", &xx, &yy);
        int nod1 = first[xx] + cnt;
        int nod2 = first[yy] + cnt;
        if (nod1 > nod2)
            swap(nod1, nod2);
        printf("%d\n", query(nod1, nod2 + 1));
    }
    return 0;
}