Cod sursa(job #2048599)

Utilizator EuAlexOtaku Hikikomori EuAlex Data 26 octombrie 2017 12:40:30
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.59 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

vector <int> G[100001];
vector <int> v, lev;
int first[100001];
int rmq[200002][32];
int lg2[200002];

void dfs(int nod = 1, int nivel = 1) {
    v.push_back(nod);
    lev.push_back(nivel);
    first[nod] = v.size() - 1;

    for(int i = 0; i < G[nod].size(); ++ i) {
        dfs(G[nod][i], nivel + 1);

        v.push_back(nod);
        lev.push_back(nivel);
    }
}

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

    int n, t;
    scanf("%d%d", &n, &t);

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

    dfs();

    int m = lev.size();
    for(int i = 0; i < m; ++ i) {
        rmq[i][0] = i;
    }

    for(int i = 1; i < 32; ++ i) {
        for(int j = 0; j + (1 << i) - 1 < m; ++ j) {
            rmq[j][i] = rmq[j][i - 1];

            if(lev[rmq[j][i]] > lev[rmq[j + (1 << (i - 1))][i - 1]]) {
                rmq[j][i] = rmq[j + (1 << (i - 1))][i - 1];
            }
        }
    }

    for(int i = 2; i <= m; ++ i) {
        lg2[i] = lg2[i / 2] + 1;
    }

    for(int i = 1; i <= t; ++ i) {
        int x, y, l, r;
        scanf("%d%d", &x, &y);
        x = first[x];
        y = first[y];
        if(x > y) {
            swap(x, y);
        }

        l = lg2[y - x + 1];
        r = rmq[x][l];
        if(lev[r] > lev[rmq[y - (1 << l) + 1][l]]) {
            r = rmq[y - (1 << l) + 1][l];
        }

        printf("%d\n", v[r]);
    }

    return 0;
}