Pagini recente » Cod sursa (job #2716156) | Cod sursa (job #3224937) | Cod sursa (job #1815682) | Cod sursa (job #1155165) | Cod sursa (job #1497955)
#include<cstdio>
using namespace std;
const int nMax = 100005, lMax = 20;
int val[nMax], urm[nMax], lst[nMax], e[nMax * 2], nivel[nMax * 2], rmq[lMax][nMax * 2], prim[nMax], lg[nMax * 2];
int n, m, k;
void dfs(int nod, int lv){
e[++k] = nod;
prim[nod] = k;
rmq[0][k] = k;
nivel[k] = lv;
int u = lst[nod], vec = val[u];
while(u){
dfs(vec, lv + 1);
e[++k] = nod;
rmq[0][k] = k;
nivel[k] = lv;
u = urm[u];
vec = val[u];
}
}
int minim(int a, int b){
return a < b ? a : b;
}
void mRmq(){
for(int i = 2 ; i <= k ; ++i) lg[i] = lg[i >> 1] + 1;
for(int i = 1 ; i <= lg[k] ; ++i){
for(int j = 1 ; j <= k - (1 << i) + 1 ; ++j){
if(nivel[rmq[i - 1][j]] < nivel[rmq[i - 1][j + (1 << (i - 1))]]){
rmq[i][j] = rmq[i - 1][j];
}else{
rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
}
}
}
int lca(int a, int b){
a = prim[a];
b = prim[b];
if(a > b){
int aux = a;
a = b;
b = aux;
}
int diff = b - a + 1;
int l = lg[diff];
if(nivel[rmq[l][a]] < nivel[rmq[l][a + diff - (1<< l)]]){
return e[rmq[l][a]];
}
return e[rmq[l][a + diff - (1<< l)]];
}
int main (){
FILE *in = fopen("lca.in","r");
fscanf(in,"%d%d",&n,&m);
for(int i = 2, x; i <= n ; ++i){
fscanf(in,"%d", &x);
val[i - 1] = i;
urm[i - 1] = lst[x];
lst[x] = i - 1;
}
dfs(1, 1);
mRmq();
FILE *out = fopen("lca.out","w");
for(int i = 1, x, y; i <= m ; i++){
fscanf(in,"%d%d",&x,&y);
fprintf(out,"%d\n",lca(x, y));
}
fclose(in);
fclose(out);
return 0;
}