Pagini recente » Cod sursa (job #383978) | Cod sursa (job #2676120) | Cod sursa (job #1829818) | Cod sursa (job #637900) | Cod sursa (job #2080199)
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
#define f first
#define s second
#define NMAX 100001
using namespace std;
vector<int> a[NMAX];
int i, nrElem, k, x, y, rmq[18][2*NMAX], lgParc, lvl[NMAX], firstAp[NMAX], nr;
int min_euler(int x, int y){
if (lvl[x]<=lvl[y]) return x; else return y;
}
void parcurge_euler(int poz, int niv){
vector<int>::iterator it;
rmq[0][++lgParc]=poz; lvl[poz]=niv; firstAp[poz]=lgParc;
for (it=a[poz].begin();it!=a[poz].end();++it) {
parcurge_euler(*it, niv+1);
rmq[0][++lgParc]=poz;
}
}
void make_rmq(){
int i, j;
///rmq[x][y]=minimul pe intervalul[x, x+2^y-1]
for (i=1;(1<<i)<=lgParc;++i)
for (j=1;j+(1<<(i-1))<=lgParc;++j) {
rmq[i][j]=min_euler(rmq[i-1][j], rmq[i-1][j+(1<<(i-1))]);
}
}
int main(){
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d%d", &nrElem, &k);
for (i=2;i<=nrElem;++i) {
scanf("%d", &x); a[x].push_back(i);
}
lgParc=0; parcurge_euler(1, 0);
make_rmq();
for (i=1;i<=k;i++) {
scanf("%d%d", &x, &y);if (x==y) {printf("%d\n", x); continue;}
x=firstAp[x]; y=firstAp[y]; if (x>y) swap(x,y);
nr=log2(y-x);
printf("%d\n", min_euler(rmq[nr][x], rmq[nr][y-(1<<nr)+1]));
}
return 0;
}