Cod sursa(job #409240)

Utilizator samuel91Asofronie Samuel samuel91 Data 3 martie 2010 15:24:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include <vector> 
#include <fstream> 
using namespace std; 
#define MAX_N 100005 
#define MAX_L 20 

#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it) 

int K, N, M; 
int L[MAX_N << 1], H[MAX_N << 1],Lg[MAX_N << 1], First[MAX_N]; 
int Rmq[MAX_L][MAX_N << 2]; 

vector <int> G[MAX_N];  
ifstream fin ("lca.in"); 
ofstream fout ("lca.out"); 

void citire() 
{    
fin >> N >> M; 
   
for(int i = 2; i <= N; ++i)     
{        
int x;         
fin >> x;        
G[x].push_back(i);     
} 
} 
void dfs(int nod, int lev) 
{ 
H[++K] = nod; //nodul actual este adaugat in reprezentarea Euler a arborelui 
L[K] = lev; //se retine nivelul fiecarei pozitii din reprezentarea Euler a arborelui    
First[nod] = K; //se retine si prima aparitie a fiecarui nod in reprezentarea Euler a arborelui 
foreach(G[nod]) 
{       
dfs(*it, lev+1);          
H[++K] = nod;        
L[K] = lev;     
} 
}
void rmq() 
{ 
//in Rmq[i][j] va fi nodul de nivel minim dintre pozitiile (j, j + 2^i - 1) din reprezentarea Euler a arborelui     
for(int i = 2; i <= K; ++i)        
Lg[i] = Lg[i >> 1] + 1;     
for(int i = 1; i <= K; ++i)         
Rmq[0][i] = i;  
for(int i = 1; (1 << i) < K; ++i)         
for(int j = 1; j <= K - (1 << i); ++j)        
{            
int l = 1 << (i - 1); 
        
Rmq[i][j] = Rmq[i-1][j];             
if(L[Rmq[i-1][j + l]] < L[Rmq[i][j]])                 
Rmq[i][j] = Rmq[i-1][j + l];         
} 
} 

int lca(int x, int y) 
{ 
//LCA-ul nodurilor x si y va fi nodul cu nivel minim din secventa (First[x], First[y]) din reprezentarea Euler a arborelui 
   
int diff, l, sol, sh;    
int a = First[x], b = First[y];     
if(a > b) swap(a, b);   
diff = b - a + 1;    
l = Lg[diff];    
sol = Rmq[l][a];     
sh = diff - (1 << l);   
if(L[sol] > L[Rmq[l][a + sh]]) 
sol = Rmq[l][a + sh]; 
    
return H[sol]; 
} 

 
int main() 
{     
citire();    
dfs(1, 0);     
rmq();   
while(M--)    
{        
int x, y;        
fin >> x >> y;        
fout << lca(x, y) << "\n";     
} 
}