Pagini recente » Diferente pentru utilizator/anamaria20 intre reviziile 6 si 7 | Borderou de evaluare (job #2492106) | Cod sursa (job #2806904)
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n, m, a[20][100001], lg2[100001], lvl[100001];
vector<int> g[100001];
void read()
{
in >> n >> m;
for(int i = 2; i <= n; ++i) {
in >> a[0][i];
g[a[0][i]].push_back(i);}
}
void prec()
{
for(int i = 2; i <= n; ++i)
lg2[i] = lg2[i/2] + 1;
for(int i = 1; (1<<i) <= n; ++i)
for(int j = 1; j <= n; ++j)
a[i][j] = a[i-1][a[i-1][j]];
}
void dfs(int nod)
{
for(auto i : g[nod]) {
lvl[i] = lvl[nod] + 1;
dfs(i);
}
}
int lca(int x, int y)
{
if(lvl[x] < lvl[y])
swap(x, y);
while(lvl[x] != lvl[y]) {
x = a[lg2[lvl[x] - lvl[y]]][x];
}
if(x == y) {
return x;
}
for(int i = lg2[lvl[x]]; i >= 0; --i)
if(a[i][x] != a[i][y]) {
x = a[i][x];
y = a[i][y];
}
return a[0][x];
}
void afis()
{
dfs(1);
int x, y;
while(m--) {
in >> x >> y;
out << lca(x, y) << '\n';
}
}
int main()
{
read();
prec();
afis();
return 0;
}