Pagini recente » Atasamentele paginii Profil CN_Dobreanu_Ionita | Istoria paginii runda/suma | Istoria paginii runda/pregatire-monthly8-ziua1 | Monitorul de evaluare | Cod sursa (job #996899)
Cod sursa(job #996899)
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX_N=100100;
int e[3*MAX_N];
int v[3*MAX_N];
int f[MAX_N];
vector<int> A[MAX_N];
int LOG[3*MAX_N];
int rmq[20][3*MAX_N];
void pregen(int n) {
for(int i=1;i<=n;i++) {
rmq[0][i]=i;
}
for(int k=1;(1<<k)<=n;k++) {
for(int i=1;(i+(1<<k)-1)<=n;i++) {
if(v[rmq[k-1][i]]<v[rmq[k-1][i+(1<<(k-1))]]) {
rmq[k][i]=rmq[k-1][i];
}
else {
rmq[k][i]=rmq[k-1][i+(1<<(k-1))];
}
}
}
LOG[1]=1;
for(int i=2;i<=n;i++)
LOG[i]=LOG[i/2]+1;
}
int lca(int x,int y) {
x=f[x];
y=f[y];
if(x>y)
swap(x,y);
int poz;
int k=LOG[y-x+1]-1;
if(v[rmq[k][x]]<v[rmq[k][y-(1<<k)+1]]) {
poz=rmq[k][x];
}
else {
poz=rmq[k][y-(1<<k)+1];
}
return e[poz];
}
void dfs(int nod,int lv) {
e[++e[0]]=nod;
v[e[0]]=lv;
f[nod]=e[0];
for(vector<int>::iterator it=A[nod].begin(); it!=A[nod].end(); ++it) {
dfs(*it,lv+1);
e[++e[0]]=nod;
v[e[0]]=lv;
}
}
int main() {
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
for(int i=2;i<=n;i++) {
int x;
scanf("%d",&x);
A[x].push_back(i);
}
dfs(1,0);
pregen(e[0]);
for(int i=1;i<=m;i++) {
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}