Pagini recente » Cod sursa (job #418861) | Cod sursa (job #912495) | Cod sursa (job #2235903) | Cod sursa (job #2725219) | Cod sursa (job #2032810)
#include <cstdio>
using namespace std;
FILE *in,*out;
const int nmax = 100005;
const int logmax = 20;
int last[nmax],dest[nmax],next[nmax],cont,euler[2*nmax],pos[nmax*2];
int rmq[nmax*4][logmax],lg[nmax*2];
void buildtree(int dad,int node)
{
cont ++;
dest[cont] = node;
next[cont] = last[dad];
last[dad] = cont;
}
int ind;
void computeeuler(int node)
{
if(node != 0)
{
euler[++ind] = node;
if(pos[node] == 0)
pos[node] = ind;
int x = last[node];
while(x != 0)
{
computeeuler(dest[x]);
euler[++ind] = node;
x = next[x];
}
}
}
void precompute()
{
for(int i = 2;i <= ind;i ++)
lg[i] = lg[i >> 1] + 1;
}
int min(int a,int b)
{
if(a < b)
return a;
return b;
}
int main()
{
in = fopen("lca.in","r");
out = fopen("lca.out","w");
int n,m;
fscanf(in,"%d %d",&n,&m);
for(int i = 1; i < n; i ++)
{
int x;
fscanf(in,"%d",&x);
buildtree(x,i+1);
}
computeeuler(1);
for(int i = 1;i <= ind;i ++){
rmq[i][0] = euler[i];
//printf("%d ",euler[i]);
}
//printf("\n");
precompute();
for(int j = 1;j <= lg[ind];j ++){
for(int i = 1;i <= ind;i ++){
rmq[i][j] = min(rmq[i][j-1],rmq[i + (1 << (j-1))][j-1]);
//printf("leng = %d poz = %d rmq = %d\n",j,i,rmq[i][j]);
}
}
//posibila greseala pt ca la mn euler e invers
for(int i = 1;i <= m;i ++)
{
int x,y;
fscanf(in,"%d %d",&x,&y);
int node1 = pos[x];
int node2 = pos[y];
if(node1 > node2)
{
int aux = node2;
node2 = node1;
node1 = aux;
}
int dif = lg[node2-node1];
fprintf(out,"%d\n",min(rmq[node1][dif],rmq[node2- (1 << dif) + 1][dif]));
}
return 0;
}