Cod sursa(job #1622678)

Utilizator irimiecIrimie Catalin irimiec Data 1 martie 2016 13:28:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.3 kb
#include <bits/stdc++.h>

using namespace std;

#define pub push_back
const int MAXN = 100010, LOGN = 20;
int n, m;
int father[MAXN], lft[MAXN];
int eR[(MAXN << 4)][LOGN];
vector<int> childs[MAXN], h;

void read() {
    assert(freopen("lca.in", "r", stdin));
    assert(freopen("lca.out", "w", stdout));

    assert(scanf("%d%d", &n, &m));
    for(int i = 2; i <= n; ++i) {
        assert(scanf("%d", father + i));
        childs[father[i]].pub(i);
    }
}

void euler(int nod, int niv) {
    lft[nod] = h.size();
    eR[h.size()][0] = nod;
    h.pub(niv);

    for(auto child : childs[nod]) {
        euler(child, niv + 1);

        eR[h.size()][0] = nod;
        h.pub(niv);
    }
}

void buildRMQ() {
    int s = h.size();
    for(int j = 1; (1 << j) <= s; ++j) {
        for(int i = 0; i + (1 << j) - 1 < s; ++i) {
            eR[i][j] = min(eR[i][j-1], eR[i + (1 << (j-1))][j-1]);
        }
    }
}

int queryRMQ(int a, int b) {
    int k = int(log2(b - a + 1));
    return min(eR[a][k], eR[b - (1 << k) + 1][k]);
}

int main() {
    read();

    euler(1, 0);

    buildRMQ();

    int a, b;
    while(m--) {
        scanf("%d%d", &a, &b);
        a = lft[a]; b = lft[b];
        if(a > b)
            swap(a, b);
        printf("%d\n", queryRMQ(a, b));
    }

}