Pagini recente » Cod sursa (job #1738530) | Cod sursa (job #2663390) | Cod sursa (job #726055) | Cod sursa (job #777977) | Cod sursa (job #1464837)
#include <fstream>
#include <algorithm>
#include <vector>
#include <bitset>
using namespace std;
ofstream fout("lca.out");
ifstream fin("lca.in");
const int NMAX = 100005;
int n, m, lg;
int Euler[NMAX * 2], Nivel[NMAX * 2], Poz[NMAX];
int ST[NMAX][20];
bitset<NMAX> Viz;
vector<int> Arbore[NMAX];
void citire()
{
fin >> n >> m;
for(int i=2, x; i<=n; i++) {
fin >> x;
Arbore[x].push_back(i);
}
}
void parcurgere_euler(int nod, int nivel)
{
Euler[++lg] = nod;
Nivel[lg] = nivel;
Poz[nod] = lg;
Viz[nod] = true;
for(auto x : Arbore[nod]) {
if(!Viz[x])
parcurgere_euler(x, nivel + 1);
Euler[++lg] = nod;
Nivel[lg] = nivel;
}
}
void rmq()
{
for(int i=1; i<=lg; i++) ST[i][0] = i;
for(int j=1; (1<<j)<=lg; j++) {
for(int i=1; i+(1<<j)-1<=lg; i++) {
if(Nivel[ST[i][j-1]] < Nivel[ST[i+(1<<(j-1))][j-1]])
ST[i][j] = ST[i][j-1];
else
ST[i][j] = ST[i+(1<<(j-1))][j-1];
}
}
}
void lca(int x, int y)
{
int a, b, k;
a = Poz[x], b = Poz[y];
if(a > b) swap(a, b);
k = log2(b - a + 1);
if(Nivel[ST[a][k]] <= Nivel[ST[b-(1<<k)+1][k]])
fout << Euler[ST[a][k]] << '\n';
else
fout << Euler[ST[b-(1<<k)+1][k]] << '\n';
}
int main()
{
citire();
parcurgere_euler(1, 0);
rmq();
for(int i=1, x, y; i<=m; i++) {
fin >> x >> y;
lca(x, y);
}
return 0;
}