Pagini recente » Cod sursa (job #1712835) | Cod sursa (job #2035112) | Cod sursa (job #1201005) | Cod sursa (job #3132804) | Cod sursa (job #930051)
Cod sursa(job #930051)
#include<cstdio>
#include<cassert>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iostream>
#include<fstream>
#include<queue>
using namespace std;
int u, vis[100005], ind[100005], num[100005], pos[100005], init[200005], p2[400005], dp[18][400005];
vector<int> graph[100005];
void rmq(){
p2[2] = 1;
int t = 2;
while(t <= u){
t = t << 1;
p2[t] = p2[t >> 1] + 1;
}
for(int i = 3; i < t; ++i)
if(!p2[i])
p2[i] = p2[i - 1];
for(int i = 1; i <= u; ++i)
dp[0][i] = init[i];
int x;
for(int i = 1; i <= p2[u] + 1; ++i)
for(int j = 1; j <= u; ++j){
x = j + (1 << (i - 1));
if(x <= u)
dp[i][j] = min(dp[i - 1][j], dp[i - 1][x]);
else
dp[i][j] = dp[i - 1][j];
}
}
int query(int left, int right){
int p = p2[right - left + 1];
return min(dp[p][left], dp[p][left + (right - left + 1) - (1 << p)]);
}
void bfs(){
int n = 0;
queue<int> q;
vis[1] = 1;
ind[1] = ++n;
num[n] = 1;
q.push(1);
while(!q.empty()){
int now = q.front();
q.pop();
for(int i = 0; i < graph[now].size(); ++i)
if(!vis[graph[now][i]]){
vis[graph[now][i]] = 1;
ind[graph[now][i]] = ++n;
num[n] = graph[now][i];
q.push(graph[now][i]);
}
}
}
void dfs(int x){
vis[x] = 1;
init[++u] = ind[x];
pos[x] = u;
for(int i = 0; i < graph[x].size(); ++i)
if(!vis[graph[x][i]]){
dfs(graph[x][i]);
init[++u] = ind[x];
}
}
int main(){
ifstream in("lca.in");
ofstream out("lca.out");
int n, m, x;
in >> n >> m;
for(int i = 2; i <= n; ++i){
in >> x;
graph[x].push_back(i);
graph[i].push_back(x);
}
bfs();
memset(vis, 0, sizeof(vis));
dfs(1);
rmq();
int y;
for(int i = 0; i < m; ++i){
in >> x >> y;
if(pos[x] > pos[y])
swap(x, y);
out << num[query(pos[x], pos[y])] << "\n";
}
return 0;
}