Cod sursa(job #1400029)

Utilizator smallOneAdina Mateescu smallOne Data 25 martie 2015 03:01:18
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#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 <string>
#include <ctime>
#include <cassert>
#include <utility>

using namespace std;

#define LIM 100005
#define LG 20

int dp[LG][LIM], level[LIM], n, m, a, b;

int stramos(int nod, int str) {
    int newS = nod;
    for(int k = 0; k < LG; k++) {
        if( (1 << k) & str) {
            newS = dp[k][newS];
        }
    }
    return newS;
}

int calc(int a, int b) {
    if(level[a] != level[b]) {
        int dif = abs(level[a] - level[b]);
        if(level[a] > level[b]) {
            a = stramos(a, dif);
        } else {
            b = stramos(b, dif);
        }
    }
    if(a == b) {
        return a;
    }
    for(int k = LG - 1; k >= 0; k--) {
        if(dp[k][a] != dp[k][b]) {
            a = dp[k][a];
            b = dp[k][b];
        }
    }
    return dp[0][a];
}

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

    scanf("%d %d", &n, &m);
    level[1] = 1;
    for(int i = 2; i <= n; i++) {
        scanf("%d", &a);
        dp[0][i] = a;
        level[i] = level[a] + 1;
    }

    for(int k = 1; k < LG; k++) {
        for(int i = 1; i <= n; i++) {
            dp[k][i] = dp[k - 1][dp[k - 1][i]];
        }
    }

    for(int i = 0; i < m; i++) {
        scanf("%d %d", &a, &b);
        printf("%d\n", calc(a, b));
    }

	return 0;
}