Pagini recente » Cod sursa (job #2287057) | Cod sursa (job #134456) | Cod sursa (job #2530252) | Cod sursa (job #2704252) | Cod sursa (job #1525922)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int nmax = 100050;
int n, m;
vector < int > Graf[nmax], euler, niv, logaritm, prmAp;
int rmq[20][2 * nmax];
void parcEuler(int poz){
euler.push_back(poz);
prmAp[poz] = euler.size();
for(int i = 0; i < Graf[poz].size(); ++i){
if( !prmAp[ Graf[poz][i] ] ){
niv[ Graf[poz][i] ] = niv[poz] + 1;
parcEuler( Graf[poz][i]);
euler.push_back(poz);
}
}
}
void rangeMinQuerry(){
int s;
for(int i = 1; (1 << i) <= euler.size(); ++i){
for(int j = 1; j <= euler.size() - (1 << i) + 1; ++j){
s = 1 << (i - 1);
rmq[i][j] = niv[ rmq[i - 1][j] ] < niv[ rmq[i - 1][j + s] ] ? rmq[i - 1][j] : rmq[i - 1][j + s];
}
}
}
int main()
{
f>>n>>m;
niv.resize(n + 1, 0);
prmAp.resize(n + 1, 0);
for(int i = 2, x; i <= n; ++i){
f>>x;
Graf[x].push_back(i);
}
parcEuler(1);
for(int i = 0; i < euler.size(); ++i){
rmq[0][i + 1] = euler[i];
}
rangeMinQuerry();
logaritm.push_back(-1);
for(int i = 1; i <= euler.size(); ++i) logaritm.push_back( logaritm[ (i >> 1) ] + 1 );
/*
for(int i = 0; (1 << i) <= euler.size(); ++i){
for(int j = 1; j <= euler.size() - (1 << i) + 1; ++j){
g<<rmq[i][j]<<' ';
}
g<<'\n';
}*/
int diff, trm1, trm2, sol, lg;
for(int i = 1, x, y; i <= m; ++i){
f>>x>>y;
if(prmAp[y] < prmAp[x]){
swap(x, y);
}
lg = logaritm[prmAp[y] - prmAp[x] + 1];
trm1 = rmq[ lg ][prmAp[x]];
trm2 = rmq[ lg ][ prmAp[y] - ( 1 << lg ) + 1 ];
sol = niv[trm1] < niv[trm2] ? trm1 : trm2;
g<<sol<<'\n';
}
return 0;
}