Pagini recente » Cod sursa (job #244852) | Borderou de evaluare (job #964853) | Borderou de evaluare (job #1608559) | Rezultatele filtrării | Cod sursa (job #1753024)
#include <fstream>
#include <iostream>
#include <vector>
std::vector <int> v[100001];
int l[200005];
int e[200005];
int pos[100001];
int mins[100001][20];
int lg[200005];
int j;
int n;
void
min()
{
int index;
for (index = 1; index <= 2 * n - 1; ++index)
{
mins[index][0] = index;
}
for (j = 1; (1 << j) < 2 * n - 1; ++j)
{
for (index = 1; index < 2 * n - 1; ++index)
{
if (index + (1 << j) > 2 * n - 1)
{
break;
}
if (l[mins[index + (1 << (j - 1))][j - 1]] < l[mins[index][j - 1]])
{
mins[index][j] = mins[index + (1 << (j - 1))][j - 1];
}
else
{
mins[index][j] = mins[index][j - 1];
}
}
}
}
void
build(int node,
int level)
{
unsigned int i;
if (not pos[node])
{
pos[node] = j;
}
e[j] = node;
l[j] = level;
++j;
for (i = 0; i < v[node].size(); ++i)
{
build(v[node][i],
level + 1);
e[j] = node;
l[j] = level;
++j;
}
}
int main()
{
std::ifstream mama("lca.in");
std::ofstream tata("lca.out");
int m;
int index;
int p;
int temp;
mama >> n >> m;
for (index = 2; index <= n; ++index)
{
mama >> p;
v[p].push_back(index);
}
j = 1;
build(1, 0);
min();
lg[1] = 0;
for (index = 2; index < 2 * n; ++index)
{
lg[index] = lg[index >> 1] + 1;
}
for (index = 0; index < m; ++index)
{
mama >> p >> j;
if (pos[p] > pos[j])
{
std::swap(p, j);
}
p = pos[p];
j = pos[j];
temp = j - p + 1;
if (l[mins[p][lg[temp]]] < l[mins[j - (1 << lg[temp]) + 1][lg[temp]]])
{
tata << e[mins[p][lg[temp]]] << '\n';
}
else
{
tata << e[mins[j - (1 << lg[temp]) + 1][lg[temp]]] << '\n';
}
}
return 0;
}