Pagini recente » Borderou de evaluare (job #2057327) | Cod sursa (job #2501353) | Borderou de evaluare (job #692015) | Cod sursa (job #1988468) | Cod sursa (job #1800228)
#include <cstdio>
#define MAXN 100000
#define LOG 20
int k, n, r, lista[MAXN+1], nxt[MAXN+1], val[MAXN+1], eu[2*MAXN+1], h[2*MAXN+1], pos[MAXN+1], lg[2*MAXN+1];
int rmq[LOG][MAXN*4];
inline int mini(int a, int b){
return (a < b ? a : b);
}
inline int maxi(int a, int b){
return (a > b ? a : b);
}
inline void adauga(int x, int y)
{
val[++r] = y;
nxt[r] = lista[x];
lista[x] = r;
}
void dfs(int nod, int a)
{
int p;
eu[++k] = nod;
pos[nod] = k;
h[k] = a;
p = lista[nod];
while(p)
{
dfs(val[p], a+1);
eu[++k] = nod;
h[k] = a;
p = nxt[p];
}
}
void calc()
{
int i, log;
for(i=1; i<=k; ++i)
rmq[0][i] = i;
for(log = 1; (1<<log)<=k; ++log)
for(i=1; i+(1<<log)-1<=k; ++i)
if(h[rmq[log-1][i]] < h[rmq[log-1][i+(1<<(log-1))]])
rmq[log][i] = rmq[log-1][i];
else rmq[log][i] = rmq[log-1][i+(1<<(log-1))];
}
int query(int a, int b)
{
int l;
if(a == b)
return a;
l = lg[b-a+1];
if(h[rmq[l][a]] < h[rmq[l][b-(1<<l)+1]])
return rmq[l][a];
return rmq[l][b-(1<<l)+1];
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int i, x, y, q;
scanf("%d%d", &n, &q);
lg[2] = 1;
for(i=3; i<=2*n; ++i)
lg[i] = lg[i/2]+1;
for(i=2; i<=n; ++i)
{
scanf("%d", &x);
adauga(x, i);
}
dfs(1, 0);
calc();
for(i=1; i<=q; ++i)
{
scanf("%d%d", &x, &y);
printf("%d\n", eu[query(mini(pos[x], pos[y]), maxi(pos[x], pos[y]))]);
}
return 0;
}