Pagini recente » Cod sursa (job #491076) | Cod sursa (job #678253) | Cod sursa (job #586521) | Cod sursa (job #2316571) | Cod sursa (job #2734098)
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int INF = 0x3f3f3f3f3f3f3f3f3f;
int n, q, e;
int log[300100], rmq[300100][23], first[100100];
bool fr[100100];
vector<int> euler;
vector<vector<int>> adj;
void eulerDfs(int node)
{
fr[node] = 1;
euler.push_back(node);
first[node] = min(first[node], (int)euler.size() - 1);
for(auto it: adj[node])
{
if(!fr[it])
{
eulerDfs(it);
euler.push_back(node);
}
}
}
void precalc()
{
for(int i = 2; i <= e; i++)
log[i] = log[i / 2] + 1;
for(int i = 0; i < e; i++)
rmq[i][0] = euler[i];
for(int j = 1; j <= log[e]; j++)
for(int i = 0; i + (1 << log[j]) - 1 < e; i++)
rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
}
int lca(int x, int y)
{
x = first[x];
y = first[y];
if(x > y)
swap(x, y);
int len = y - x + 1;
//cout << x << ' ' << y << ' ' << log[len] << '\n';
return min(rmq[x][log[len]], rmq[y - (1 << log[len]) + 1][log[len]]);
}
int main()
{
memset(first, INF, sizeof first);
in >> n >> q;
adj.resize(n + 5);
for(int i = 2; i <= n; i++)
{
int x;
in >> x;
adj[x].push_back(i);
}
eulerDfs(1);
e = euler.size();
precalc();
/*
for(int i = 0; i < e; i++)
cout << euler[i] << ' ';
cout << '\n';
for(int i = 0; i < e; i++)
{
cout << "i: " << i << '\n';
for(int j = 0; i + (1 << j) - 1 < e; j++)
cout << j << ' ' << rmq[i][j] << '\n';
cout << '\n';
}
*/
while(q--)
{
int x, y;
in >> x >> y;
out << lca(x, y) << '\n';
}
return 0;
}