Pagini recente » Cod sursa (job #716736) | Cod sursa (job #314991) | Cod sursa (job #966290) | Cod sursa (job #3181347) | Cod sursa (job #709103)
Cod sursa(job #709103)
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n,m,e[200020],lv[200020],pap[200020],nr,rmq[200020][25],mpoz[200020][25],lg[200020],p2[31];
vector<int> v[100010];
void pEuler(int nod, int niv) {
int i;
if(pap[nod]==0)
pap[nod]=nr+1;
for(i=0;i!=v[nod].size();++i) {
e[++nr]=nod; lv[nr]=niv;
pEuler(v[nod][i],niv+1);
}
e[++nr]=nod; lv[nr]=niv;
}
void initRMQ() {
int i,j,l;
for(i=1;i<=nr;++i) {
rmq[i][0]=lv[i];
mpoz[i][0]=i;
}
for(i=1;(1<<i)<=nr;++i)
for(j=1;j <= nr - (1<<i) + 1;++j) {
l=(1<<(i-1));
if(rmq[j][i-1] < rmq[j+l][i-1])
mpoz[j][i] = mpoz[j][i-1];
else
mpoz[j][i] = mpoz[j+l][i-1];
rmq[j][i] = min(rmq[j][i-1], rmq[j+l][i-1]);
}
}
inline int query(int el1, int el2) {
if(el1>el2) {
el1^=el2;
el2^=el1;
el1^=el2;
}
int minpoz,dist = lg[el2 - el1];
if(rmq[el1][dist] < rmq[el2-p2[dist]][dist])
minpoz = mpoz[el1][dist];
else
minpoz = mpoz[el2 - p2[dist]][dist];
return e[minpoz];
}
int main() {
int i,p,n1,n2;
in >> n >> m;
for(i=2;i<=n;++i) {
in >> p;
v[p].push_back(i);
}
for(i=2;i<=2*n;++i)
lg[i] = lg[i>>1] + 1;
n2=1;
for(i=1;i<=30;i++) {
n2*=2;
p2[i]=n2;
}
pEuler(1,1);
initRMQ();
for(i=1;i<=m;++i) {
in >> n1 >> n2;
out << query(pap[n1],pap[n2]) << "\n";
}
return 0;
}