Cod sursa(job #773341)

Utilizator PlayLikeNeverB4George Marcus PlayLikeNeverB4 Data 1 august 2012 15:12:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 kb
#include <cstdio>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <ctype.h>
#include <cstring>
#include <ctime>

using namespace std;

#define MAXN 100005
vector<int> graph[MAXN];
int L[MAXN], T[MAXN], P[MAXN];
int k, t, x, y, N, M, H;

void levels(int node, int level) {
    L[node] = level;
    H = max(H, level);

    for(size_t i = 0; i < graph[node].size(); i++)
        levels(graph[node][i], level + 1);
}

void dfs(int node, int upper) {
    P[node] = upper;

    if((L[node] + 1) % k == 0)
        upper = node;

    for(size_t i = 0; i < graph[node].size(); i++)
        dfs(graph[node][i], upper);
}

int lca(int x, int y) {
    while(P[x] != P[y])
        if(L[x] >= L[y])
            x = P[x];
        else
            y = P[y];
    while(x != y)
        if(L[x] >= L[y])
            x = T[x];
        else
            y = T[y];
    return x;
}

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

    scanf("%d %d", &N, &M);

    for(int i = 2; i <= N; i++) {
        scanf("%d", &t);
        graph[t].push_back(i);
        T[i] = t;
    }

    H = 0;
    levels(1, 0);

    for(k = 1; k * k <= H; k++);
    k--;

    dfs(1, 0);

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

        printf("%d\n", lca(x, y));
    }

	return 0;
}