Pagini recente » Cod sursa (job #1816489) | Cod sursa (job #412770) | Cod sursa (job #63094) | Cod sursa (job #1598429) | Cod sursa (job #3293254)
#include <bits/stdc++.h>
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt")
//#define fin cin
//#define fout cout
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int nmax = 1e5+1;
int n,m;
array<int,2*nmax> exponent,last;
vector<int> g[nmax];
struct cv{
int depth,node;
static cv min(cv a, cv b){
return ((a.depth < b.depth) ? a : b);
}
} rmq[32][nmax],info[nmax];
int gindex;
void process(int node, int depth) {
info[++gindex] = {depth,node};
last[node] = gindex;
}
bool vis[nmax];
void dfs(int node = 1, int depth = 1) {
process(node,depth);
vis[node] = true;
for (auto x : g[node]) {
if(!vis[x])dfs(x,depth+1);
process(node,depth);
}
}
int query(int l, int r) {
int e = exponent[r - l + 1];
return cv::min(rmq[e][l],rmq[e][r - (1<<e) + 1]).node;
}
int lca(int x, int y) {
int l = last[x];
int r = last[y];
if (l > r) swap(l,r);
return query(l,r);
}
int main() {
fin >> n >> m;
for (int i = 2; i <= n; i++) {
int x; fin >> x;
g[x].push_back(i);
g[i].push_back(x);
}
dfs();
for (int i = 2; i <= gindex; i++)
exponent[i] = 1 + exponent[i/2];
for (int i = 1; i <= gindex; i++) rmq[0][i] = info[i];
for (int p = 1; (1<<p) <= gindex; p++) {
for (int i = 1; i <= gindex; i++) {
int j = min(gindex,i+(1<<(p-1)));
rmq[p][i] = cv::min(rmq[p-1][i],rmq[p-1][j]);
}
}
while (m--) {
int x,y;
fin >> x >> y;
fout << lca(x,y) << '\n';
}
return 0;
}