Pagini recente » Cod sursa (job #574941) | Cod sursa (job #1567070) | Cod sursa (job #2885784) | Cod sursa (job #1725754) | Cod sursa (job #2959846)
#include <fstream>
#include <vector>
#define NMAX 100005
#define MAX_LOG 18
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
struct ok{
long long nod, nivel;
};
vector <long long> children[NMAX];
ok euler[2 * NMAX];
long long log2[2 * NMAX];
long long k;
ok table[2 * NMAX][MAX_LOG + 1];
long long first[2 * NMAX];
void dfs(long long node, long long niv)
{
long long 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()
{
long long i;
for (i = 2; i < 2 * NMAX; ++i)
log2[i] = log2[i / 2] + 1;
}
long long query(long long left, long long right)
{
long long len = right - left + 1;
long long log = log2[len];
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;
}
int main()
{
long long 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);
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;
}
}
for (i = 1; i <= q; ++i)
{
in >> a >> b;
long long first_a = first[a];
long long first_b = first[b];
out << query(min(first_a, first_b) - 1, max(first_a, first_b) - 1) << '\n';
}
return 0;
}