Pagini recente » Cod sursa (job #1485583) | Cod sursa (job #3139870) | Cod sursa (job #603370) | Cod sursa (job #468531) | Cod sursa (job #731024)
Cod sursa(job #731024)
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
#define MAXN 100002
#define MAXLOG 16
int Lv[MAXN], T[MAXN], First[MAXN], Grup[MAXN], lg[MAXN];
int Q[MAXN*2];
vector<int> G[MAXN];
int N, M, E;
int i, x, y;
int Ans;
int P[(1<<8)][8][8];
int RMQ[MAXLOG][MAXN/4 + 2];
void df(int nod)
{
vector<int>::iterator it;
Lv[nod] = Lv[T[nod]] + 1;
Q[++E] = nod;
First[nod] = E;
for (it = G[nod].begin(); it != G[nod].end(); ++it){
df(*it);
Q[++E] = nod;
Grup[E>>3] |= (1<<(E&7));
}
}
inline void precalcul()
{
int mask, i, j, minim;
int Nr[8];
memset(Nr, 0, sizeof(Nr));
for (mask = 0; mask < (1<<8); ++mask)
for (i = 0; i < 8; ++i){
Nr[i] = 0; minim = i;
P[mask][i][i] = i;
for (j = i+1; j < 8; ++j){
if (mask & (1<<j))
Nr[j] = Nr[j-1] - 1;
else
Nr[j] = Nr[j-1] + 1;
if (Nr[minim] > Nr[j])
minim = j;
P[mask][i][j] = minim;
}
}
}
inline void rmq_grupe()
{
int i, j, l, W;
W = (E >> 3) + 1;
lg[1] = 0;
for (i = 2; i < W; ++i)
lg[i] = lg[i>>1] + 1;
for (i = 0; i < W; ++i)
RMQ[0][i] = Q[P[Grup[i]][0][7] + (i<<3)];
for (i = 1; (1<<i) <= W; ++i)
for (j = 0; j < W - (1<<i) + 1; ++j)
{
l = 1<<(i-1);
RMQ[i][j] = RMQ[i-1][j];
if (Lv[ RMQ[i][j] ] > Lv[ RMQ[i-1][j+l] ])
RMQ[i][j] = RMQ[i-1][j+l];
}
}
inline void rmq(int x, int y)
{
int diff, l, sh;
if (x > y)
swap(x,y);
if ( (x >> 3) == (y >> 3) ){
Ans = Q[ P[Grup[x>>3]][x&7][y&7] + ((x>>3)<<3 )];
return;
}
int grupx, grupy;
grupx = x >> 3;
grupy = y >> 3;
if (Lv[Ans] > Lv[ Q[ P[Grup[grupx]][x&7][7] + (grupx << 3) ] ] )
Ans = Q[ P[Grup[grupx]][x&7][7] + (grupx << 3) ];
if (Lv[Ans] > Lv[ Q[ P[Grup[grupy]][0][y&7] + (grupy <<3) ] ] )
Ans = Q[ P[Grup[grupy]][0][y&7] + (grupy<<3) ];
x = (x >> 3) + 1;
y = (y >> 3) - 1;
if (x <= y){
diff = y - x + 1;
l = lg[diff];
sh = diff - (1<<l);
if (Lv[Ans] > Lv[ RMQ[l][x] ])
Ans = RMQ[l][x];
if (Lv[Ans] > Lv[ RMQ[l][x + sh] ])
Ans = RMQ[l][x + sh];
}
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d %d",&N,&M);
for (i = 2; i <= N; ++i){
scanf("%d",&T[i]);
G[T[i]].push_back(i);
}
E = -1;
df(1);
precalcul();
rmq_grupe();
for (i = 1; i <= M; ++i){
scanf("%d %d",&x,&y);
Ans = x;
rmq(First[x], First[y]);
printf("%d\n",Ans);
}
return 0;
}