Pagini recente » Cod sursa (job #2089266) | Cod sursa (job #2520454) | Cod sursa (job #1236125) | Cod sursa (job #599884) | Cod sursa (job #717978)
Cod sursa(job #717978)
#include<stdio.h>
#include<assert.h>
#include<algorithm>
#include<vector>
using namespace std;
const int knmax = 220005;
int numbers, qrys, size, vis[knmax / 2], last_seen[knmax / 2], pows[knmax], rmq[20][knmax];
vector<int> graph[knmax / 2];
void read(){
assert(freopen("lca.in", "r", stdin) != NULL);
scanf("%d%d", &numbers, &qrys);
int aux;
for(int i = 2; i <= numbers; ++i){
scanf("%d", &aux);
graph[aux].push_back(i);
}
}
void dfs(int x){
vis[x] = 1;
rmq[0][++size] = x;
for(vector<int>::iterator it = graph[x].begin(); it < graph[x].end(); ++it)
if(!vis[*it]){
dfs(*it);
rmq[0][++size] = x;
}
}
void solve(){
dfs(1);
for(int i = 1; i <= size; ++i)
last_seen[rmq[0][i]] = i;
int i, j;
for(j = 1; j <= 18; ++j)
for(i = 1; i <= size; ++i)
if(i + (1 << (j - 1)) > size)
rmq[j][i] = rmq[j - 1][i];
else
rmq[j][i] = min(rmq[j - 1][i], rmq[j - 1][i + (1 << (j - 1))]);
for(i = 1, j = 0; i <= size; ++i){
if(i == 1 << (j + 1))
++j;
pows[i] = j;
}
}
inline int query(int left, int right){
int len = right - left + 1;
return min(rmq[pows[len]][left], rmq[pows[len]][right - (1 << pows[len]) + 1]);
}
void write(){
assert(freopen("lca.out", "w", stdout) != NULL);
int aux_x, aux_y;
for(int i = 1; i <= qrys; ++i){
scanf("%d%d", &aux_x, &aux_y);
if(last_seen[aux_x] > last_seen[aux_y])
swap(aux_x, aux_y);
printf("%d\n", query(last_seen[aux_x], last_seen[aux_y]));
}
}
int main(){
read();
solve();
write();
return 0;
}