Pagini recente » Cod sursa (job #1077957) | Cod sursa (job #2402721) | Cod sursa (job #682352) | Cod sursa (job #2841239) | Cod sursa (job #2080191)
#include<cstdio>
#include<vector>
#include<algorithm>
#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], lg[NMAX];
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 lca(int x, int y){
if (x>y) swap(x,y);
int d=lg[y-x+1]-1;
return min_euler(rmq[d][x], rmq[d][y-(1<<d)+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);
lg[1]=1; for (i=2;i<=lgParc;i++) lg[i]=lg[i>>1]+1;
make_rmq();
for (i=1;i<=k;i++) {
scanf("%d%d", &x, &y);
if (x==y) {printf("%d\n", x); continue;}
printf("%d\n", lca(firstAp[x],firstAp[y]));
}
return 0;
}