Cod sursa(job #689254)

Utilizator informatician28Andrei Dinu informatician28 Data 24 februarie 2012 11:55:10
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 kb
#include<fstream> 
#include<vector> 
#include<algorithm>
#define DIM 100001
#define pb push_back
#define INF 0x3f3f3f3f
using namespace std; 

ifstream in("lca.in");
ofstream out("lca.out");

vector< int > G[DIM];
int Tata[DIM], N, contor, Euler[DIM *2], Lev[DIM*2], First[DIM], minim, pos, M, a, b, A[DIM << 4];
int hsol, sol, st, dr;
bool viz[DIM];

void DFs(int node, int level)
{
    viz[node] = 1;
    Lev[++contor] = level;
    Euler[contor] = node;
    First[node] = contor;
    for(vector< int > ::iterator it = G[node].begin(); it != G[node].end(); ++it)
        if( !viz[*it] )
        {
            DFs(*it, level+1);
            
        Euler[++contor] = node; 
        Lev[contor] = level;
        }
}
void Build(int nod, int st, int dr)
{
    if(st == dr)
	{
		A[nod] = st;
		return;
	}
    else 
    {
        int mid =st + (dr-st)/2;
	    Build(2*nod, st, mid);
	    Build(2*nod+1, mid+1, dr);

	if(Lev[A[2*nod]] <= Lev[A[2*nod+1]])
		A[nod] = A[2*nod];
	else
		A[nod] = A[2*nod+1];
    }
}
void Query(int nod, int li, int lf)
{
    if(st <= li && lf <= dr)
	{
		if(Lev[A[nod]] < hsol)
			sol = Euler[A[nod]],
			hsol = Lev[A[nod]];
		return;
	}
    else
    {
        int mid = li + (lf-li)/2;
	    if(st <= mid) Query(2*nod, li, mid);
	    if(mid < dr)  Query(2*nod+1, mid+1, lf);
    }
}
int lca(int x, int y)
{
     st = First[x]; 
     dr = First[y]; 
    
    if( st > dr )
        swap(st, dr);
    sol = hsol = INF;
    Query(1, 1, contor);
    return sol;
}
int main()
{
    int i, a, b;
    
    in >> N >> M;
    for(i = 2; i <= N; i++)
    {
        in >> Tata[i]; 
        G[Tata[i]].pb(i);
    }
    
    DFs(1, 0);
    Build(1, 1, contor);
    
    for(i = 1; i <= M; i++)
    {
        in >> a >> b;
        
        out << lca(a,b) << '\n';
    }
}