Pagini recente » Cod sursa (job #2047425) | Cod sursa (job #1712397) | Cod sursa (job #215965) | Cod sursa (job #2960462) | Cod sursa (job #2959764)
#include <fstream>
#include <vector>
#define NMAX 100005
#define MAX_LOG 17
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
struct ok{
int nod, nivel;
};
vector <int> children[NMAX];
ok euler[2 * NMAX];
int log2[2 * NMAX];
int k;
ok table[2 * NMAX][MAX_LOG];
int first[NMAX];
void dfs(int node, int niv)
{
int i;
euler[k++].nod = node;
euler[k - 1].nivel = niv;
if (first[node] == 0)
first[node] = k;
for (i = 0; i < children[node].size(); ++i)
{
dfs(children[node][i], niv + 1);
euler[k++].nod = node;
euler[k - 1].nivel = niv;
}
}
void buildLog()
{
int i;
for (i = 2; i <= NMAX; ++i)
log2[i] = log2[i / 2] + 1;
}
int query(int left, int right)
{
int len = right - left + 1;
int log = log2[len];
//out << left << " " << right << " " << log << '\n';
//out << table[left][log].nivel << " " << table[right - (1 << log) + 1][log].nivel << '\n';
//out << table[left][log].nivel << " " << table[right - (1 << log) + 1][log].nivel << '\n';
if (table[left][log].nivel <= table[right - (1 << log) + 1][log].nivel)
return table[left][log].nod;
else
return table[right - (1 << log) + 1][log].nod;
//return min(table[left][log].nivel, table[right - (1 << log) + 1][log].nivel);
}
int main()
{
int n, q, i, j, a, b, p;
in >> n >> q;
for (i = 2; i <= n; ++i)
{
in >> a;
children[a].push_back(i);
}
k = 0;
dfs(1, 1);
/*for (i = 0; i < k; ++i)
out << euler[i].nod << " ";
out << '\n';
for (i = 0; i < k; ++i)
out << euler[i].nivel << " ";
out << '\n';
for (i = 1; i <= n; ++i)
out << first[i] << " ";*/
buildLog();
for (i = 0; i < k; ++i)
{
table[i][0].nod = euler[i].nod;
table[i][0].nivel = euler[i].nivel;
}
for (p = 1; p <= MAX_LOG; ++p)
{
for (i = 0; i + (1 << p) - 1 < k; ++i)
{
table[i][p].nivel = min(table[i][p - 1].nivel, table[i + (1 << (p - 1))][p - 1].nivel);
if (table[i][p].nivel == table[i][p - 1].nivel)
table[i][p].nod = table[i][p - 1].nod;
else
table[i][p].nod = table[i + (1 << (p - 1))][p - 1].nod;
}
}
//out << '\n';
for (i = 1; i <= q; ++i)
{
in >> a >> b;
int first_a = first[a];
int first_b = first[b];
//out << min(first_a, first_b) - 1 << " " << max(first_a, first_b) - 1 << '\n';
out << query(min(first_a, first_b) - 1, max(first_a, first_b) - 1) << '\n';
}
/*for (p = 1; p <= MAX_LOG; ++p)
{
for (i = 0; i + (1 << p) - 1 < k; ++i)
out << table[i][p].nivel << " ";
out << '\n';
}*/
return 0;
}