Cod sursa(job #1027956)

Utilizator sziliMandici Szilard szili Data 13 noiembrie 2013 12:20:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.46 kb
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <math.h>

using namespace std;

typedef struct rmq_elem{
    int val;
    int index;
} RMQ_ELEM;

int n,m;

vector<int> adjacencyList[100001];
int h[200002];
int hSize=0;
int eulerVisitOrder[200002];

int eulerDepths[200002];
//this data structure is based on the euler depths
RMQ_ELEM rmqStructure[200002][20];

void readData(){
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    scanf("%d %d", &n, &m);

    int nr;
    for (int i=2; i<=n; i++){
        scanf("%d", &nr);
        adjacencyList[nr].push_back(i);
    }
}

void dfs(int node, int depth){
    h[hSize] = node;
    eulerDepths[hSize] = depth;

    if (eulerVisitOrder[node] == 0){
        eulerVisitOrder[node] = hSize;
    }

    hSize++;

    for (int i=0; i<adjacencyList[node].size(); i++){
        int newNode = adjacencyList[node][i];

        dfs(newNode, depth+1);
        h[hSize] = node;
        eulerDepths[hSize] = depth;
        hSize++;
    }
}

void buildRmqDataStructure(){

    for (int i=0; i<hSize; i++){
        RMQ_ELEM e;
        e.val = eulerDepths[i];
        e.index = i;
        rmqStructure[i][0] = e;
    }

    for (int j=1; j<=18; j++){
        for (int i=0; i<hSize; i++){

            if ((i-1 + (1<<j))  < hSize){

                if (rmqStructure[i][j-1].val < rmqStructure[i + (1 << (j-1))][j-1].val) {
                    rmqStructure[i][j] = rmqStructure[i][j-1];
                } else {
                    rmqStructure[i][j] = rmqStructure[i + (1 << (j-1))][j-1];
                }
            }

        }
    }

}

int getMin(int a, int b){
    int k = (int)log2((double) b-a + 1);

    if (rmqStructure[a][k].val < rmqStructure[b - (1 << k) + 1][k].val){
        return h[rmqStructure[a][k].index];
    }
    else {
        return h[rmqStructure[b - (1 << k) + 1][k].index];
    }
}

void readCommands(){
    int a,b;
    for (int i=0; i<m; i++){
        scanf("%d %d", &a, &b);

        int minVal;

        if (eulerVisitOrder[a] < eulerVisitOrder[b]){
            minVal = getMin(eulerVisitOrder[a], eulerVisitOrder[b]);
        } else {
            minVal = getMin(eulerVisitOrder[b],eulerVisitOrder[a]);
        }


        printf("%d\n", minVal);
    }

}

int main()
{
    readData();
    dfs(1, 0);
    buildRmqDataStructure();
    readCommands();

    return 0;
}