Cod sursa(job #771612)

Utilizator mi5humihai draghici mi5hu Data 26 iulie 2012 16:53:17
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <stdio.h>
#include <vector>
#include <cmath>
#define NMAX 100002
#define MMAX 4000004
#define LIMIT 25

using namespace std;
vector<int> nodes[NMAX];
vector< pair<int, int> > Euler;
int PMin[MMAX][LIMIT];
int Pos[NMAX];

void left_root_right(int node, int h) {
     Euler.push_back(make_pair(node, h));
     if (Pos[node] == 0) {
        Pos[node] = Euler.size() - 1;
     }
     
     vector<int>::iterator it;
     for (it = nodes[node].begin(); it != nodes[node].end(); it++) {
          left_root_right(*it, h + 1);
          Euler.push_back(make_pair(node, h));          
     }     
}

int read_() {
    int n, m, parent;
    scanf("%d%d", &n, &m);  
    for (int i = 2; i <= n; i++) {
        scanf("%d", &parent);
        nodes[parent].push_back(i);        
    }
    
    Euler.push_back(make_pair(-1, -1));
    left_root_right(1, 0);
    return m;  
}

// Pozitia minimului;
int min_(int p1, int p2) {
    return (Euler[p1].second <= Euler[p2].second ? p1 : p2);
}

int get_ancestor(int x, int y) {
    int k = (int)(floor(log2(y - x)));
    return min_(PMin[x][k], PMin[y - (1 << k) + 1][k]);
}

void compute_rmq() {
     int n = Euler.size() - 1;
     for (int i = 1; i <= n; i++) {
         PMin[i][0] = i;
     }   
     for (int j = 1; j <= LIMIT; j++) {
         int Lung_Interv = 1 << j;
         for (int i = 1; i + Lung_Interv - 1 <= n; i++) {
             PMin[i][j] = min_(PMin[i][j - 1], PMin[i + (1 << (j - 1))][j - 1]);
         }  
     }  
}

int minVal(int x, int y) {
    return (x < y ? x : y);
}

int maxVal(int x, int y) {
    return (x > y ? x : y);       
}

void solve_(int m) {
    int x, y;
    for (int i = 0; i < m; i++) { 
        scanf("%d%d", &x, &y);
        int anc = get_ancestor(minVal(Pos[x], Pos[y]), maxVal(Pos[x], Pos[y]));
        printf("%d\n", Euler[anc].first);
    } 
}

int main() {
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    
    int m = read_();
    compute_rmq();
    solve_(m);
    
    return 0;
}