Cod sursa(job #737660)

Utilizator andreipasalauPasalau Andrei andreipasalau Data 19 aprilie 2012 22:56:56
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <fstream>
#include <stdlib.h>
#include <cmath>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n, m, *vector[100001], euler[100001 * 2][2], pozitie = 0;
int *M[200002];
int poz[100001 * 2];

void eulerFunction(int nr, int h){
	euler[pozitie][0] = nr;
    euler[pozitie++][1] = h;
    for( int i = 1; i <= vector[nr][0]; i++ )
    {
        eulerFunction(vector[nr][i], h + 1);
        euler[pozitie][0] = nr;
        euler[pozitie++][1] = h;
    }
	
}

void procesare() {
	int i,j;
    for(int i=0;i<2*n-1;i++)
    {
        M[i]=(int*)malloc((log2(2*n-1-i)+1)*sizeof(int));
        M[i][0]=i;
    }
    for(j = 1; 1<<j <= 2*n-1; j++)
        for(i=0; i+(1<<j)-1 < 2*n-1; i++)
            if(euler[M[i][j-1]][1] < euler[M[i+(1<<(j-1))][j-1]][1])
                M[i][j]=M[i][j-1];
            else    
				M[i][j]=M[i+(1<<(j-1))][j-1];
			
	 for(int i=0;i<2*n-1;i++)
            poz[euler[i][0]] = i;
}

int rmq(int i, int j) {
	int k = (int)log2(j-i+1);
    if(euler[M[i][k]][1] <= euler[M[j-(1<<k)+1][k]][1])
        return euler[M[i][k]][0];
    else 
		return euler[M[j-(1<<k)+1][k]][0];
}

int query(int i, int j){
	int u, v;
	if(poz[i] < poz[j]){
		u = poz[i];
		v = poz[j];
	}
	else {
		u = poz[j];
		v = poz[i];
	}
	return rmq(u, v);
}



int main(){
	int a, b;
	f >> n >> m;
	int alfa;
	for(int i=1;i<=n;i++) {
        vector[i]=(int*)malloc(sizeof(int));
        vector[i][0]=0;
	}
	for(int i = 2; i <= n ; i++){
		f >> alfa;
		vector[alfa][0]++;
		vector[alfa] = (int*)realloc(vector[alfa],(vector[alfa][0]+1)*sizeof(int));
		vector[alfa][vector[alfa][0]] = i;
	}
	eulerFunction(1, 0);
	procesare();
	for(int i = 0; i < m; i++) {
		f >> a;
		f >> b;
		g << query(a, b) << endl;
	}
	return 0;
}