Cod sursa(job #2264182)

Utilizator b10nd3Oana Mancu b10nd3 Data 19 octombrie 2018 20:58:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include<iostream>
#include<fstream>
#include<vector>

using namespace std;

#define MAX 100005

vector <int> G[MAX];
int euler[MAX*3], nivel[MAX*3], firstApp[MAX];
int rmq[20][MAX*3], lg[MAX*3];
int k, n;

void bfs(int nod, int niv){
	
	k++;
	firstApp[nod] = k;
	euler[k] = nod;
	nivel[k]=niv;
	
	vector <int> :: iterator it;
	for(it=G[nod].begin(); it!=G[nod].end();it++){
		
		bfs(*it,niv+1);
		
		k++;
		euler[k]=nod;
		nivel[k]=niv;
	}

}


int lca(int x, int y){
	if(x>y) swap(x,y);
	int dif=y-x+1;
	int sol = rmq[ lg[dif] ][ x ];
	if( nivel[ rmq[lg[dif]][ x + dif - (1<<lg[dif]) ] ] < nivel[ rmq[ lg[dif] ][ x ] ] )
	    sol = rmq[lg[dif]][ x + dif - (1<<lg[dif]) ];
	return euler[sol];
}



int main(){
	FILE  *in = fopen("lca.in","r"); 
	FILE *out = fopen("lca.out","w");
	int x, i,j, m, y;
	fscanf(in,"%i%i",&n,&m);
    
    //citire date
    for(i=2;i<=n;i++){
    	fscanf(in,"%i",&x);
    	G[x].push_back(i);
	}
	
	bfs(1,0); // => reprezentarea Euler, nivel, prima aparitie a unui nod  
	
	
	//RMQ();
	lg[1] = 0;
	for(i=2; i<=k; i++) lg[i] = lg[i>>1]+1;
	
	for(i=1;i<=k;i++) rmq[0][i] = i;
	
	for( i=1; (1<<i) <= k; i++ )
	    for(j = 1; j <= k - (1<<i)+1; j++ ){
	    	rmq[i][j] = rmq[i-1][ j ];
	    	if( nivel[ rmq[i-1][ j + (1<<(i-1)) ] ] < nivel[rmq[i][j]] )
	    	    rmq[i][j] = rmq[i-1][ j + (1<<(i-1)) ];
		}  
		
		 
	for(i=1;i<=m;i++){
		fscanf(in,"%i%i",&x,&y);
		fprintf( out,"%i\n",lca(firstApp[x],firstApp[y]) );
	}
    
	fclose(in); fclose(out);
	return 0;
}