Cod sursa(job #2264023)

Utilizator b10nd3Oana Mancu b10nd3 Data 19 octombrie 2018 19:06:22
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.46 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;
	}

}


void RMQ(){
	int i,j;
	
	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)) ];
		}  
}


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 + lg[dif] ] ] < nivel[ rmq[ lg[dif] ][ x ] ] )
	    sol = rmq[lg[dif]][ x + lg[dif] ];
	return euler[sol];
}



int main(){
	ifstream in("lca.in"); ofstream out("lca.out");
	int x, i, m, y;
	in>>n>>m;
    
    //citire date
    for(i=2;i<=n;i++){
    	in>>x;
    	G[x].push_back(i);
	}
	
	bfs(1,0); // => reprezentarea Euler, nivel, prima aparitie a unui nod  
	RMQ();
	
	for(i=1;i<=m;i++){
		in>>x>>y;
		out<<lca(firstApp[x],firstApp[y])<<'\n';
	}
    
	in.close(); out.close();
	return 0;
}