Cod sursa(job #1742306)

Utilizator AplayLazar Laurentiu Aplay Data 16 august 2016 11:37:19
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include <bits/stdc++.h>

#define NMAX 100001
#define MAXLOG 17

#define minn(a, b) a < b ? a : b
#define pb push_back

using namespace std;

int N, M, p[NMAX], euler[10 * NMAX], level[NMAX], first[NMAX], rmq[10 * NMAX][MAXLOG], x, y, tmp;
vector<int> graph[NMAX];

void buildEuler(int node, int currLevel) {
    euler[++euler[0]] = node;

    if (first[node] == 0) {
        level[node] = currLevel;
        first[node] = euler[0];
    }

    for(vector<int>::iterator it = graph[node].begin(); it < graph[node].end(); ++it) {
        buildEuler(*it, currLevel + 1);
        euler[++euler[0]] = node;
    }
}

void buildRMQ() {
    for (int it = 0; it < euler[0]; ++it) {
        rmq[it][0] = it + 1;
    }

    for (int j = 1; (1 << j) <= euler[0]; ++j) {
        for (int i = 0; i + (1 << j) - 1 < euler[0]; ++i) {
            if (euler[rmq[i][j - 1]] < euler[rmq[i + (1 << (j - 1))][j - 1]]) {
                rmq[i][j] = rmq[i][j - 1];
            } else {
                rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
            }
        }
    }
}

int queryRMQ(int left, int right) {
    int k = (int) log2(right - left + 1);
    return minn(euler[rmq[left][k]], euler[rmq[right - (1 << k) + 1][k]]);
}

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

    scanf("%d%d", &N, &M);
    for (int it = 2; it <= N; ++it) {
        scanf("%d", p + it);
        graph[p[it]].pb(it);
    }

    buildEuler(1, 0);
    //for (int it = 1; it <= euler[0]; ++it) printf("%d ", euler[it]);
    //printf("\n");
    //for (int it = 1; it <= euler[0]; ++it) printf("%d ", first[it]);
    //printf("\n");
    buildRMQ();

    for (int it = 0; it < M; ++it) {
        scanf("%d%d", &x, &y);

        //printf("%d %d ", first[x], first[y]);

        if (first[x] > first[y]) {
            tmp = x; x = y; y = tmp;
        }

        printf("%d\n", queryRMQ(first[x] - 1, first[y] - 1));
    }

    return 0;
}