Pagini recente » Cod sursa (job #3265919) | Cod sursa (job #386166) | Cod sursa (job #2161118) | Cod sursa (job #2914104) | Cod sursa (job #2959841)
#include <fstream>
#include <vector>
#define NMAX 200005
#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 <= 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];
//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()
{
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);
/*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;
long long first_a = first[a];
long long 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;
}