Pagini recente » Cod sursa (job #1695487) | Cod sursa (job #2274843) | Cod sursa (job #2119840) | Cod sursa (job #2676966) | Cod sursa (job #673841)
Cod sursa(job #673841)
#include <fstream>
#include <vector>
#define nmax 100004
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector<int> G[nmax];
int Op,N,NM;
int Lg[nmax*2],Poz[nmax*2];
int V[nmax*2];
int RMQ[18][2*nmax];
inline int _min(int a,int b){if(a<b)return a;return b;}
void DF(int nod)
{
int i;
V[++NM] = nod;
Poz[nod] = NM;
for(i=0;i<G[nod].size();i++)
{
DF(G[nod][i]);
V[++NM] = nod;
}
}
int LCA(int a,int b) //return RMQ(Poz[a],Poz[b]);
{
int x = Poz[a],y = Poz[b];
if(x>y)x^=y^=x^=y;
int nivel,diferenta;
nivel = Lg[y-x+1];
diferenta = y-x+1-(1<<nivel);
return _min(RMQ[nivel][x],RMQ[nivel][x+diferenta]);
}
int main()
{
int x,y,i,j;
in>>N>>Op;
for(i=2;i<=N;i++)
{
in>>x;
G[x].push_back(i);
}
//reprezentare EULER
DF(1);
//RMQ
Lg[1] = 0;
for(i=2;i<=NM;i++)Lg[i]=Lg[i/2]+1;
for(i=1;i<=NM;i++)RMQ[0][i]=V[i];
for(i=1;(1<<i)<=NM;++i)
{
for(j=1;j<=NM-(1<<i)+1;j++)
{
RMQ[i][j] = _min(RMQ[i-1][j],RMQ[i-1][j+(1<<i-1)]);
}
}
while(Op--)
{
in>>x>>y;
//afisez cel mai apropiat stramos comun
out<<LCA(x,y)<<'\n';
}
return 0;
}