Pagini recente » Borderou de evaluare (job #376072) | Borderou de evaluare (job #375958) | Borderou de evaluare (job #588690) | Autentificare | Cod sursa (job #3364064)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>>tree;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int LOGMAX = 19;//log2(10^5)
const int NMAX = 1e5+1;
int anc[NMAX][LOGMAX];//anc[i][j]=nodul care se afla 2^j in sus fata de nodul i
vector<int>depth;
void CalcAnc(int crt,int depthCrt, int father) {
depth[crt] = depthCrt;
anc[crt][0] = father;
for (int i = 1; i <= depthCrt; ++i) {
int up = anc[crt][i - 1];
anc[crt][i] = anc[up][i - 1];
}
for (int i = 0; i < tree[crt].size(); ++i) {
if (tree[crt][i] != father) {
CalcAnc(tree[crt][i], depthCrt + 1, crt);
}
}
}
int cb(int u, int v) {
for (int i = LOGMAX-1; i >= 0; --i) {
if (anc[u][i] !=anc[v][i]) {
u = anc[u][i];
v = anc[v][i];
}
}
return anc[u][0];
}
int BinaryLifting(int u, int v) {
if (depth[u] < depth[v]) {
swap(u, v);
}
for (int i = LOGMAX-1; i >=0; --i) {
if (depth[u] - (1 << i) >= depth[v]) {
u = anc[u][i];
}
}
if (u == v) {
return v;
}
return cb(u, v);
}
int main()
{
int n,q;
fin >> n>>q;
int father;
depth.resize(n+1);
tree.resize(n + 1);
for (int i = 2; i <= n; ++i) {
fin >> father;
tree[father].push_back(i);
tree[i].push_back(father);
}
CalcAnc(1, 0, 0);
int u, v;
while (q)
{
fin >> u >> v;
fout << BinaryLifting(u, v) << "\n";
q--;
}
return 0;
}
//=^..^=