Pagini recente » Cod sursa (job #554232) | Cod sursa (job #1509414) | Cod sursa (job #133368) | Istoria paginii utilizator/leongs | Cod sursa (job #1805814)
//LCA - Lowest Common Ancestor
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define NMAX 100005
#define MMAX 2000000
#define MAXL 20
int n, m, x, y, crt;
vector <int> noduri[NMAX]; //vectorul de noduri
int euler[2*NMAX]; //parcurgerea euler
int level[2*NMAX]; //vectorul de niveluri
int poz[NMAX]; //vectorul de pozitii
int lg[2*NMAX];
int RMQ[MAXL][4*NMAX];
void parcurgereEuler(int nod, int nivel) {
euler[++crt] = nod; //nodul este adaugat in reprezentarea Euler a arborelui
level[crt] = nivel; //retinem nivelul fiecarei pozitii din reprezentarea Euler a arborelui
poz[nod] = crt; //retinem prima aparitie a fiecarui nod in reprezentarea Euler a arborelui
for(unsigned i = 0 ; i < noduri[nod].size() ; i++) {
parcurgereEuler(noduri[nod][i], nivel+1);
euler[++crt] = nod;
level[crt] = nivel;
}
}
void rmq() {
int i, j, k;
for(i = 2 ; i <= crt ; i++)
lg[i] = lg[i/2] + 1; //initializare
for(i = 1 ; i <= crt ; i++)
RMQ[0][i] = i; //initializare
for(i = 1 ; (1 << i) < crt ; i++)
for(j = 1 ; j <= crt - (1 << i) ; j++) {
k = 1 << (i - 1);
RMQ[i][j] = RMQ[i-1][j];
if(level[RMQ[i-1][j+k]] < level[RMQ[i][j]])
RMQ[i][j] = RMQ[i-1][j+k];
}
}
int minim(int x, int y) {
if(level[x] > level[y]) return y;
return x;
}
int lca(int x, int y) {
int a = poz[x], b = poz[y], aux;
int len, mutare;
if(a > b) { aux = a; a = b; b = aux; }
len = lg[b-a+1];
mutare = b - a + 1 - (1 << len); //cu cat ma mut
return euler[minim(RMQ[len][a], RMQ[len][a+mutare])];
}
int main()
{
int i;
fin>>n>>m;
noduri[0].push_back(0);
noduri[0].push_back(1);
for(i = 1 ; i < n ; i++) {
fin>>x;
noduri[x].push_back(i+1);
}
parcurgereEuler(1, 0);
rmq();
for(i = 1 ; i <= m ; i++) {
fin>>x>>y;
fout<<lca(x, y)<<endl;
}
fin.close();
fout.close();
return 0;
}