Pagini recente » Borderou de evaluare (job #1544897) | Cod sursa (job #2998389) | Cod sursa (job #2761522) | Cod sursa (job #224453) | Cod sursa (job #2772700)
#include <fstream>
#include <vector>
#include <queue>
const int maxn=1e5+2;
const int inalt=19;
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
int dads[maxn], depth[maxn], findNode[maxn];
vector<int> sons[maxn];
vector<int> linear;//aici tinem liniarizarea; impingem elementele unul cate unul
void dfs(int i){
linear.push_back(i);
findNode[i]=linear.size()-1;
for(int j=0; j<sons[i].size(); j++){
depth[sons[i][j]]=depth[i]+1;//cresc in valuri adancimea
dfs(sons[i][j]);
linear.push_back(i);//bag noile noduri in vecor de liniarizre
findNode[i]=linear.size()-1;//si marchez ca sa stiu de unde le iau
}
}
int rmq[maxn<<1][inalt], powers[inalt+1], floorExponent[maxn<<1];
int query(int lo, int hi){
int gap=hi-lo+1;
if(depth[rmq[lo][floorExponent[gap]]]<depth[rmq[hi-powers[floorExponent[gap]]+1][floorExponent[gap]]]){
return rmq[lo][floorExponent[gap]];
}
else
return rmq[hi-powers[floorExponent[gap]]+1][floorExponent[gap]];
}
int main() {
int n, m; cin>>n>>m;
for(int i=0; i<n-1; i++){
cin>>dads[i+2];//citim direct tatii
sons[dads[i+2]].push_back(i+2);
}
dfs(1);
powers[0]=1;
int index=1;
while(powers[index-1]<linear.size()){
powers[index]=powers[index-1]<<1;
index++;//ne generam puterile lui 2
}
floorExponent[1]=0;
int nextPower=2;
for(int i=2; i<linear.size(); i++){
if(i==nextPower){
floorExponent[i]=floorExponent[i-1]+1;
nextPower<<=1;
}
else
floorExponent[i]=floorExponent[i-1];
}
for(int j=0; j<index; j++){
for(int i=1; i<=linear.size(); i++){
if(j==0){//daca avem intervale de lungime 1
rmq[i][j]=linear[i];//punem direct valoarea
}
else{//la alea mai lungi
if(depth[rmq[i][j-1]]<depth[rmq[min(i+powers[j-1], (int)linear.size())][j-1]])
rmq[i][j]=rmq[i][j-1];//punem minimul dupa adancimi
else rmq[i][j]=rmq[min(i+powers[j-1], (int)linear.size())][j-1];
}
}
}
for(int i=0; i<m; i++){
int x, y; cin>>x>>y;
x=findNode[x], y=findNode[y];
if(x<y)
swap(x, y);
cout<<query(y, x)<<"\n";
}
return 0;
}