Pagini recente » Cod sursa (job #2526471) | Cod sursa (job #2098309) | Cod sursa (job #2749478) | Cod sursa (job #453194) | Cod sursa (job #3003415)
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define MAX_N 100000
const int LOG = 25;
int n, m;
vector <vector <int> > graph;
vector <int> euler, first, height, lg;
pair <int, int> sp[40][2 * MAX_N + 1];
bitset <MAX_N + 1> viz;
void dfs(int node, int h)
{
viz[node] = 1;
first[node] = euler.size();
height[node] = h;
euler.pb(node);
for(int neighbour : graph[node])
{
if(!viz[neighbour])
{
dfs(neighbour, h + 1);
euler.pb(node);
}
}
}
void precalculate()
{
lg.resize(euler.size() + 1);
lg[1] = 0;
for(int i = 2; i <= euler.size(); i ++)
lg[i] = lg[i / 2] + 1;
}
void sparseTabel()
{
for(int i = 0; i < euler.size(); i ++)
sp[0][i].first = height[euler[i]], sp[0][i].second = euler[i];
for(int i = 1; i <= LOG; i ++)
{
int j;
for(j = 0; j + (1 << i) <= euler.size(); j ++)
{
sp[i][j] = min(sp[i - 1][j], sp[i - 1][j + (1 << (i - 1))]);
}
}
}
int query(int l, int r)
{
if(l > r)
swap(l, r);
int i = lg[r - l + 1];
// cout << i << " " << l << " " << r - (1 << i) + 1;
if(sp[i][l] < sp[i][r - (1 << i) + 1])
return sp[i][l].second;
return sp[i][r - (1 << i) + 1].second;
// return min(sp[i][l], sp[i][r - (1 << i) + 1]);
}
int main()
{
ios_base :: sync_with_stdio(0);
cin.tie(0);
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
cin >> n >> m;
graph.resize(n + 1);
first.resize(n + 1);
height.resize(n + 1);
for(int i = 2; i <= n; i ++)
{
int x;
cin >> x;
graph[x].pb(i);
}
dfs(1, 1);
//
// for(int i = 0; i < euler.size(); i ++)
// cout << euler[i] << " ";
// cout << "\n";
// for(int i = 0; i < euler.size(); i ++)
// cout << height[euler[i]] << " ";
// cout << "\n";
// cout << "\n";
// for(int x :first)
// cout << x << " ";
sparseTabel();
precalculate();
// cout << euler.size();
for(int i = 1; i <= m; i ++)
{
int x, y;
cin >> x >> y;
cout << query(first[x], first[y]) << "\n";
}
// cout << sp[3][11]. first << " " << sp[3][11].second;
// for(int i = 1; i <= 4; i ++)
// {
// for(int j = 0; j < euler.size(); j++)
// cout << sp[i][j].first << " ";
//// cout << (1 << i) << " " << j << " " << sp[i][j].first << " " << sp[i - 1][j].first<< " " << sp[i - 1][j + (1 << (i - 1))].first<< "\n";
// cout << "\n";
// }
return 0;
}