Cod sursa(job #1197194)

Utilizator Kira96Denis Mita Kira96 Data 11 iunie 2014 00:46:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.95 kb
#include<fstream>
#include<cstdio>
#include<set>
#include<stack>
#define ROF(a,b,c) for(int a=b;a>=c;--a)
#include<vector>
#include<algorithm>
#define FOR(a,b,c) for(int a=b;a<=c;++a)
#define FIT(it,e) for(vector<int>::iterator it=e.begin();it!=e.end();it++)
#include<cstring>
#include<bitset>
#include<cmath>
#include<iomanip>
#include<queue>
#define debug printf("OK!\n");
#define f cin
#define g cout
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ll unsigned long long
#define mod 666013
#define N 100100
#define LM 5
#define BMAX 1000100
#define infile "lca.in"
#define outfile "lca.out"
using namespace std;
//int dx[]={0,0,0,1,-1};
//int dy[]={0,1,-1,0,0};
ifstream f(infile);
ofstream g(outfile);
char buf[BMAX];
int buffer;
void gint(int &ans)
{
	ans=0;
	while(buf[buffer]<'0'||buf[buffer]>'9')
	{
		buffer++;
		if(buffer==BMAX-1)
		{
			f.get(buf,BMAX,EOF);
			buffer=0;
		}
	}
	while(buf[buffer]>='0'&&buf[buffer]<='9')
	{
		ans=ans*10+buf[buffer++]-'0';
		if(buffer==BMAX-1)
		{
			f.get(buf,BMAX,EOF);
			buffer=0;
		}
	}
}
vector<int> v[N],P[N];
int arb[N],T[N],F[LM][N],niv[N],t,s[N],lvl[N],poz[N],nrl,lant[N],n,q,x,a,b;
void dfs(int x,int p,int lvl)
{
	T[x]=p;
	niv[x]=lvl;
	arb[x]=1;
	
	int best=0;
	
	FIT(it,v[x])
	{
		if(!niv[*it])
		{
			dfs(*it,x,lvl+1);
			arb[x]+=arb[*it];
			if(arb[*it]>arb[best])
				best=*it;
		}
	}
	
	if(best)
	{
		lant[x]=lant[best];
		P[lant[x]].pb(x);
		poz[x]=P[lant[x]].size();
	}
	else
	{
		++nrl;
		P[nrl].pb(0);
		P[nrl].pb(x);
		poz[x]=1;
		lant[x]=nrl;
	}
}
void dfs1(int x,int p)
{
	if(poz[x]==1)
	{
		int p2=0;
		for(int po=1;po<=t;po<<=1,p2++)
			F[p2][x]=s[t-po+1];
		s[++t]=x;
		lvl[x]=t;
	}
	
	FIT(it,v[x])
		if(*it!=p)
			dfs1(*it,x);
	
	if(poz[x]==1)
		--t;
}
int lca(int a,int b)
{
	if(lant[a]==lant[b])
	{
		if(poz[a]<poz[b])
			return a;
		return b;
	}
	
	if(lvl[P[lant[a]][1]]>lvl[P[lant[b]][1]])
		swap(a,b);
	int aux=a;
	
	a=P[lant[a]][1];
	b=P[lant[b]][1];
	
	int dif=lvl[b]-lvl[a];
	int po=1;
	int t=0;
	
	for(;po<=dif;po<<=1,t++);
	po>>=1;
	t--;
	dif--;
	
	for(;dif>0;po>>=1,t--)
	{
		if(po<=dif)
		{
			dif-=po;
			b=F[t][b];
		}
	}
	if(dif!=-1)
	b=T[b];
	
	if(lant[b]==lant[a])
	{
		a=aux;
		if(poz[a]<poz[b])
			return a;
		return b;
	}
	else
		b=P[lant[b]][1];
	
	for(po=1,t=0;po<=lvl[a];po<<=1,t++);
	po>>=1;
	t--;
	
	for(;po;po>>=1,t--)
	{
		if(F[t][a]!=F[t][b])
		{
			a=F[t][a];
			b=F[t][b];
		}
	}
	a=T[a];
	b=T[b];
	if(poz[a]<poz[b])
		return a;
	return b;
}
	
int main ()
{
	f.get(buf,BMAX,EOF);
	gint(n);
	gint(q);
	FOR(i,2,n)
	{
		gint(x);
		v[x].pb(i);
	}
	dfs(1,0,1);
	FOR(i,1,nrl)
	{
		int siz=P[i].size();
		FOR(j,1,siz/2)
		{
			swap(P[i][j],P[i][siz-j]);
			swap(poz[P[i][j]],poz[P[i][siz-j]]);
		}
	}
	dfs1(1,0);
	FOR(i,1,q)
	{
		gint(a);
		gint(b);
		g<<lca(a,b)<<"\n";
	}
	return 0;
}