Pagini recente » Cod sursa (job #685907) | Cod sursa (job #3275741) | Cod sursa (job #2147905) | Cod sursa (job #1518400) | Cod sursa (job #2774407)
#include <fstream>
#include <vector>
using namespace std;
const int Nmax = 200000;
int h[Nmax + 1], l[Nmax + 1];
int rmq[Nmax + 1][21], log[Nmax + 1];
vector <int> adj[Nmax + 1];
vector <int> euler;
bool viz[Nmax + 1];
int n, k = 1;
void dfs(int node, int q = 0)
{
viz[node] = true;
euler.push_back(node);
l[node] = euler.size();
h[node] = q;
for (auto u : adj[node])
{
if (!viz[u])
{
dfs(u, q + 1);
euler.push_back(node);
}
}
}
void RMQ()
{
for (int i = 2; i <= n; i++)
{
log[i] = log[i / 2] + 1;
}
for (int i = 1; i <= n; i++)
{
rmq[i][0] = i;
}
for (int j = 1; j <= 20; j++)
{
for (int i = 1; i + (1 << j) <= n; i++)
{
int x = rmq[i][j - 1], y = rmq[i + (1 << (j - 1))][j - 1];
if (h[euler[x - 1]] < h[euler[y - 1]])
{
rmq[i][j] = x;
}
else
{
rmq[i][j] = y;
}
}
}
}
int lca(int u, int v)
{
if (l[u] > l[v])
{
swap(u, v);
}
int j = log[l[v] - l[u] + 1];
int x = rmq[l[u]][j], y = rmq[l[v] - (1 << j) + 1][j];
if (h[euler[x - 1]] < h[euler[y - 1]])
{
return euler[x - 1];
}
else
{
return euler[y - 1];
}
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
int m;
fin >> n >> m;
for (int i = 2; i <= n; i++)
{
int nr;
fin >> nr;
adj[nr].push_back(i);
}
dfs(1);
n = euler.size();
RMQ();
while (m--)
{
int u, v;
fin >> u >> v;
fout << lca(u, v) << "\n";
}
return 0;
}