Pagini recente » Cod sursa (job #2067128) | Cod sursa (job #3211627) | Cod sursa (job #2162667) | Cod sursa (job #1305567) | Cod sursa (job #1525611)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int nmax = 100050;
int n, m;
bool Frecv[2 * nmax];
vector < int > Graf[nmax], euler, niv, logaritm, prmAp;
int rmq[20][2 * nmax];
void parcEuler(int poz, int lvl){
Frecv[poz] = true;
euler.push_back(poz);
niv[poz] = lvl;
prmAp[poz] = euler.size();
for(int i = 0; i < Graf[poz].size(); ++i){
if( !Frecv[ Graf[poz][i] ] ){
parcEuler( Graf[poz][i], lvl + 1 );
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);
Graf[i].push_back(x);
}
parcEuler(1, 0);
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;
for(int i = 1, x, y; i <= m; ++i){
f>>x>>y;
diff = prmAp[y] - prmAp[x];
if(diff < 0) diff *= -1;
trm1 = rmq[ logaritm[diff] ][prmAp[x]];
trm2 = rmq[ logaritm[diff] ][ prmAp[y] - ( 1 << logaritm[diff] ) + 1 ];
sol = niv[trm1] < niv[trm2] ? trm1 : trm2;
g<<sol<<'\n';
}
return 0;
}