Pagini recente » Cod sursa (job #2108018) | Cod sursa (job #3222221) | Cod sursa (job #1643464) | Cod sursa (job #1716940) | Cod sursa (job #2294992)
#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
int euler[300001], nivel[300001], poz[100001], log[100001], niv[100001];
int lookup_table[20][300001];
vector <int> g[100001];
int i, it=0, j;
int nod_curent;
void dfs(int nod, int i){
int nod_vecin;
euler[++it]=nod;
for(i=0;i<g[nod].size();i++){
nod_vecin=g[nod][i];
j=i;
if(nivel[g[nod][i]]==-2){
nivel[g[nod][i]]=nivel[nod]+1;
dfs(g[nod][j], i);
euler[++it]=nod;
}
}
}
int main() {
FILE *fin,*fout;
int n, m, x, j, x1, y1, ans, logn, d, x2, y2, p2;
fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");
fscanf(fin,"%d%d", &n, &m);
for(i=2;i<=n;i++){
fscanf(fin,"%d", &x);
g[x].push_back(i);
g[i].push_back(x);
}
for(i=1;i<=n;i++){
nivel[i]=-2;
}
nivel[1]=0;
dfs(1, 0);
for(i=1;i<=it;i++){
lookup_table[0][i]=i;
}
for(i=1;i<=it;i++){
niv[i]=nivel[euler[i]];
}
for(i=1;i<=it;i++){
if(poz[euler[i]]==0)
poz[euler[i]]=i;
}
for(i=1;i<=it;i++){
if(niv[i]<=niv[i+1])
lookup_table[1][i]=i;
else
lookup_table[1][i]=i+1;
}
i=1;
logn=0;
while(i<it){
if(i*2<=it){
i*=2;
logn++;
}
else
i*=2;
}
p2=1;
log[1]=0;
for(i=2;i<=it+1;i++){
if(i==2*p2){
p2*=2;
log[i]=log[i-1]+1;
}
else
log[i]=log[i-1];
}
for(i=2;i<=logn;i++){
for(j=1;j+(1<<i)-1<=it;j++){
if(niv[lookup_table[i-1][j]]<=niv[lookup_table[i-1][j+(1<<i-1)]])
lookup_table[i][j]=lookup_table[i-1][j];
else
lookup_table[i][j]=lookup_table[i-1][j+(1<<i-1)];
}
}
for(j=1;j<=m;j++){
fscanf(fin,"%d%d", &x1, &y1);
if(poz[x1]<poz[y1]){
x2=poz[x1];
y2=poz[y1];
}
else{
x2=poz[y1];
y2=poz[x1];
}
d=y2-x2+1;
if(niv[lookup_table[log[d-1]][x2]]<=niv[lookup_table[log[d-1]][y2-(1<<log[d-1])+1]])
fprintf(fout,"%d\n", euler[lookup_table[log[d-1]][x2]]);
else
fprintf(fout,"%d\n", euler[lookup_table[log[d-1]][y2-(1<<log[d-1])+1]]);
}
fclose(fin);
fclose(fout);
return 0;
}