Pagini recente » Cod sursa (job #3356570) | Cod sursa (job #3355347) | Statistici Borsos Zalan (borsoszalan) | Profil donea | Cod sursa (job #3353353)
#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>
using namespace std;
const int nrMaxNoduri = 1e5;
int euler[nrMaxNoduri << 1], nivel[nrMaxNoduri << 1], pozitii[nrMaxNoduri << 1];
vector<int> lf[nrMaxNoduri+1];
int rmq[nrMaxNoduri << 1][20];
ifstream fin("lca.in");
ofstream fout("lca.out");
int poz;
void calculeazaRMQ(int n){
int l=log2(n);
for(int i=0; i<n; i++){
rmq[i][0] = i;
}
for(int j=1; j<=l; j++){
for(int i=0; i<n; i++){
if(i+(1<<(j))<=n)
//rmq[i][j]=min(rmq[i][j-1], rmq[i+(1<<(j-1))][j-1]);
if (nivel[rmq[i][j-1]] < nivel[rmq[i+(1<<(j-1))][j-1]])
rmq[i][j] = rmq[i][j-1];
else
rmq[i][j] = rmq[i+(1<<(j-1))][j-1];
}
}
}
int interogare(int a, int b)
{
if (a > b) swap(a,b);
int lung=b-a+1, k=(int)(log2(lung));
//return min(rmq[a][k], rmq[b-(1<<k)+1][k]);
if (nivel[rmq[a][k]] < nivel[rmq[b-(1<<k)+1][k]])
return rmq[a][k];
return rmq[b-(1<<k)+1][k];
}
void parcurgere(int x, int niv) {
euler[poz] = x;
nivel[poz] = niv;
pozitii[x] = poz;
poz++;
for (auto y : lf[x]) {
parcurgere(y,niv+1);
euler[poz] = x;
nivel[poz] = niv;
poz++;
}
}
int main()
{
int n, m , t;
fin >> n >> m;
for (int i = 2; i <= n; i++) {
fin >> t;
lf[t].push_back(i);
}
parcurgere(1,0);
calculeazaRMQ(poz);
int x, y;
for (int i = 0; i < m; i++) {
fin >> x >> y;
fout << euler[interogare(pozitii[x],pozitii[y])] << "\n";
}
return 0;
}