Pagini recente » Rating Trusca Fabian (Fabian_Trusca) | Istoria paginii runda/test12312312323/clasament | Monitorul de evaluare | Statistici Takacs Razvan (BombardierTati) | Cod sursa (job #595566)
Cod sursa(job #595566)
//#include <cstdio>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAXN 100010
#define MAXLGN 18
int main(){
// freopen("lca.in", "r", stdin);
// freopen("lca.out", "w", stdout);
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int N, M, i, j, a, b, qp, pos, k, lca;
static int L[MAXN<<1], E[MAXN<<1], F[MAXN<<1], dfs[MAXN], RMQ[MAXLGN][MAXN<<1], lg[MAXN<<1];
vector<int> G[MAXN];
vector<int>::iterator dp[MAXN];
// scanf("%d%d", &N, &M);
fin >> N >> M;
for(i=2; i<=N; i++){
//scanf("%d", &a);
fin >> a;
G[a].push_back(i);
}
memset(F, 0, sizeof(F));
qp=0; dfs[0]=1; dp[0]=G[1].begin(); pos=0;
while(qp>=0){
E[++pos]=dfs[qp]; L[pos]=qp;
if(!F[dfs[qp]])
F[dfs[qp]]=pos;
if(dp[qp] != G[dfs[qp]].end()){
dfs[qp+1]=*dp[qp];
++qp;
dp[qp]=G[dfs[qp]].begin();
}
else {
--qp;
++dp[qp];
}
}
for(i=1; i<=pos; i++)
RMQ[0][i]=i;
for(i=1; (1<<i)<=pos; i++)
for(j=1; j+(1<<i)-1 <= pos; j++){
if(L[RMQ[i-1][j]] < L[RMQ[i-1][j+(1<<(i-1))]])
RMQ[i][j]=RMQ[i-1][j];
else
RMQ[i][j]=RMQ[i-1][j+(1<<(i-1))];
}
lg[1]=0;
for(i=2; i<=pos; i++)
lg[i]=lg[i>>1]+1;
for(i=1; i<=M; i++){
//scanf("%d%d", &a, &b);
fin >> a >> b;
a=F[a]; b=F[b];
if(a>b)
swap(a,b);
k=lg[b-a+1];
if(L[RMQ[k][a]] < L[RMQ[k][b-(1<<k)+1]])
lca=RMQ[k][a];
else
lca=RMQ[k][b-(1<<k)+1];
//printf("%d\n", E[lca]);
fout << E[lca] << "\n";
}
return 0;
}