Cod sursa(job #737663)

Utilizator andreipasalauPasalau Andrei andreipasalau Data 19 aprilie 2012 23:11:32
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 *vector[100001], n, m;
int euler[2*100001][2], poz = 0, lg;
int pozitie[100001];
int *M[2*100001];


void eulerFunction(int nod,int nivel){
    euler[poz][0] = nod;
    euler[poz++][1] = nivel;
    for(int i = 1; i <=  vector[nod][0]; i++ ){
        eulerFunction(vector[nod][i],nivel+1);
        euler[poz][0] = nod;
        euler[poz++][1] = nivel;
    }
}

void Procesare()
{
    int i;
    for(int i = 0;i<lg;i++){
        M[i] = (int*)malloc((log2(lg-i)+1)*sizeof(int));
        M[i][0] = i;
    }
    for(int j = 1; 1<<j <= lg; j++)
        for(i = 0;i+(1<<j)-1<lg;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++)
    {
        pozitie[euler[i][0]] = i;
    }
}

int rmq(int i,int j) {
	int k;
	if (i > j){
		k = i;
		i = j;
		j = k;
	}
    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 main(){
	int alfa;
    f >> n >> m;
    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);
    lg = 2*n-1;
    Procesare();
	int u, v;
    for(int i = 0;i<m;i++){
        f >> u >> v;
        g << rmq(pozitie[u], pozitie[v]) << endl;
    }
    return 0;
}