Cod sursa(job #599025)

Utilizator floringh06Florin Ghesu floringh06 Data 27 iunie 2011 19:41:15
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

#define MAX_N 100005
#define MAX_L 20

int d[MAX_N << 1][MAX_L];
int t[MAX_N << 1], euler[MAX_N << 1], l[MAX_N << 1], first[MAX_N];
vector<int> arb[MAX_N];
int N, M, K;

void DFS (int node, int level) {
     euler[K] = node;
     l[K] = level;
     first[node] = K++;
     for (int i = 0; i < (int)arb[node].size(); ++i) {
         DFS (arb[node][i], level + 1);
         euler[K] = node;
         l[K++] = level;
     }
}

int main () {
    freopen ("lca.in", "r", stdin);
    freopen ("lca.out", "w", stdout);
    
    scanf ("%d %d", &N, &M);
    for (int i = 1; i < N; ++i) {
        scanf ("%d", t + i);
        arb[--t[i]].push_back(i);
    }
    DFS (0, 0);
    for (int i = 0; i < K; ++i) d[i][0] = i;
    
    for (int p = 1; 1 << p <= K; ++p)
        for (int i = 0; i + (1 << p) <= K; ++i)
            if (l[ d[i][p - 1] ] < l[ d[i + (1 << (p - 1))][p - 1] ])
                d[i][p] = d[i][p - 1];
            else
                d[i][p] = d[i + (1 << (p - 1))][p - 1];
                
    for (int i = 0; i < M; ++i) {
        int a, b, pe;
        scanf ("%d %d", &a, &b);
        a = first[--a];
        b = first[--b];
        if (a > b) a ^= b ^= a ^= b;
        
        for (pe = 0; 1 << pe <= b - a + 1; ++pe); --pe;
        if (l[d[a][pe]] < l[d[b - (1 << pe) + 1][pe]])
            printf ("%d\n", euler[d[a][pe]] + 1);
        else
            printf ("%d\n", euler[d[b - (1 << pe) + 1][pe]] + 1);
    }
    
    return 0;
}