Pagini recente » Monitorul de evaluare | Cod sursa (job #1506506) | Cod sursa (job #1305995) | Rating chestie chestie (Chestie) | Cod sursa (job #1098235)
#include<fstream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<queue>
#define abs(x) ((x>0)?(x):(-(x)))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define ll long long
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int Nmax = 100005;
int T,N,K;
vector<int> G[Nmax];
int mark[Nmax],L[Nmax],E[2*Nmax];
int First[Nmax],Last[Nmax];
int rmq[18][2*Nmax],lg[2*Nmax];
int broken[Nmax];
struct LCA{
int x,y,l;
} Lca[Nmax];
inline bool cmp(LCA a,LCA b){
return a.l>b.l;
}
void Dfs(int x,int depth){
mark[x]=1;
E[++E[0]]=x;First[x]=E[0];
L[x]=depth;
for(vector<int>::iterator it=G[x].begin();it!=G[x].end();++it){
if(!mark[*it]){
Dfs(*it,depth+1);
E[++E[0]]=x;
}
}
Last[x]=E[0];
}
void BuildRMQ(){
for(int i=2;i<=E[0];i++){
lg[i]=lg[i>>1]+1;
}
for(int i=1;i<=E[0];i++){
rmq[0][i]=E[i];
}
for(int i=1;(1<<i)<=E[0];i++){
for(int j=1;j+(1<<i)-1<=E[0];j++){
rmq[i][j]=rmq[i-1][j];
if( L[ rmq[i-1][j+(1<<(i-1))] ] < L[ rmq[i][j] ] ) rmq[i][j] = rmq[i-1][j+(1<<(i-1))] ;
}
}
}
int RMQ(int a,int b){
a=First[a];
b=First[b];
if(a>b) swap(a,b);
int dist=b-a;
int log=lg[dist];
int lca=rmq[log][a];
if( L[ rmq[log][a+dist-(1<<log)+1] ] < L[lca] ) lca=rmq[log][a+dist-(1<<log)+1];
return lca;
}
void Reset(){
E[0]=0;
memset(mark,0,sizeof(mark));
memset(broken,0,sizeof(broken));
for(int i=1;i<=N;i++) G[i].clear();
}
int main(){
//in>>T;
T=1;
for(;T;--T){
in>>N>>K;
Reset();
/*
for(int i=1;i<N;i++){
int x,y;
in>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
*/
for(int i=1;i<N;i++){
int x;
in>>x;
G[i+1].push_back(x);
G[x].push_back(i+1);
}
Dfs(1,1);
BuildRMQ();
for(int i=1;i<=K;i++){
int x,y;
in>>x>>y;
if(x>y) swap(x,y);
Lca[i].x=x;
Lca[i].y=y;
Lca[i].l=RMQ(x,y);
out<<Lca[i].l<<'\n';
}
/*
sort(Lca+1,Lca+K+1,cmp);
int Ans=0;
for(int i=1;i<=K;i++){
if(!broken[ Lca[i].l ] && !broken[ Lca[i].x ] && !broken[ Lca[i].y ]){
Ans++;
for(int j=First[ Lca[i].l ];j<=Last[ Lca[i].l ];j++){
broken[j]=1;
}
}
}
*/
}
return 0;
}