Pagini recente » Cod sursa (job #627191) | Cod sursa (job #749592) | Cod sursa (job #647820) | Cod sursa (job #433442) | Cod sursa (job #1224111)
// using RMQ
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
int M[100002][17];
struct NodeItem{
int parent, height;
bool once;
vector<int> kids;
};
typedef struct NodeItem Node;
int n, m, x, a, b;
vector<Node> nodes;
vector<int> et, heights;
vector<int> firstOccur;
void euler_tour(){
stack<int> st;
st.push(1);
while(!st.empty()){
int nod = st.top(); st.pop();
et.push_back(nod);
heights.push_back(nodes[nod].height);
if(firstOccur[nod] == -1) firstOccur[nod] = heights.size()-1;
if(nodes[nod].once){
nodes[nod].once = false;
for(int i = nodes[nod].kids.size()-1; i >= 0; i--){
st.push(nod);
st.push(nodes[nod].kids[i]);
}
}
}
}
void rmq_init(){
n = heights.size();
for(int i = 0; i < 100000; i++){ // todo!
for(int j = 0; j < 17; j++)
M[i][j] = 100001;
}
for (int i = 0; i < n; i++)
M[i][0] = i;
for(int j = 1; (1 << j) <= n; j++){
for (int i = 0; i + (1 << j) - 1 < n; i++)
if (heights[M[i][j - 1]] <= heights[M[i + (1 << (j - 1))][j - 1]])
M[i][j] = M[i][j - 1];
else
M[i][j] = M[i + (1 << (j - 1))][j - 1];
}
}
int lg2(int x){
int cnt = 0;
while(1 << cnt <= x){
cnt++;
}
return cnt-1;
}
int rmq(int b, int e){
if(b > e){
int aux = b;
b = e;
e = aux;
}
int min_pow = lg2(e-b+1);
if(heights[M[b][min_pow]] <= heights[M[e-(1 << min_pow)+1][min_pow]]){
return M[b][min_pow];
}
return M[e-(1 << min_pow)+1][min_pow];
}
int main(){
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &n, &m);
Node p; p.once = true;
//cin >> n >> m;
for(int i = 0; i <= n ; i++){
nodes.push_back(p);
firstOccur.push_back(-1);
}
nodes[1].parent = 1;
nodes[1].height = 0;
for(int i = 0; i < n - 1; i++){
scanf("%d", &x);
//cin >> x;
nodes[x].kids.push_back(i+2);
nodes[i+2].parent = x;
nodes[i+2].height = nodes[x].height + 1;
}
euler_tour();
rmq_init();
for(int i = 0; i < m; i++){
scanf("%d%d", &a, &b);
//cin >> a >> b;
printf("%d\n", et[rmq(firstOccur[a], firstOccur[b])]);
}
return 0;
}