Pagini recente » Cod sursa (job #2661448) | Cod sursa (job #2365446) | Cod sursa (job #140258) | Cod sursa (job #959808) | Cod sursa (job #1482668)
#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <cmath>
using namespace std;
class tree{
public:
int k=1,root;
vector<int> e;
vector<int> d;
vector<int> h;
vector<vector<int>> c;
map<int,vector<int>> N;
tree(int r){
root = r;
}
void euler(vector<int>& h,int& current, vector<int>& euler1, vector<int>& depth, int dist){
euler1.push_back(current);
depth.push_back(dist);
if (h[current] == -1)h[current] = d.size() - 1;
for (auto& i : N[current]){
euler(h,i, euler1, depth, dist + 1);
euler1.push_back(current);
depth.push_back(dist);
}
}
void preprocess(){
h.resize(k+1, -1);
euler(h,root, e, d, 0);
c.resize(d.size());
for (auto&i : c)i.resize(log2(d.size()) + 1);
rmq2(c, d);
}
void rmq2(vector<vector<int>>& M, vector<int>&A){
int i, j, N = A.size();
for (i = 0; i < N; i++)
M[i][0] = i;
for (j = 1; 1 << j <= N; j++)
for (i = 0; i + (1 << j) - 1 < N; i++)
if (A[M[i][j - 1]] < A[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 lca(int a, int b){
int p1=h[a], p2=h[b];
if (p2 < p1){
p1 ^= p2; p2 = p1^p2; p1 ^= p2;
}
int k = 0, pow = 1;
while (pow <= p2 - p1 + 1){ pow <<= 1; ++k; }
pow >>= 1;
--k;
int index = d[c[p1][k]] <= d[c[p2 - pow + 1][k]] ? c[p1][k] : c[p2 - pow + 1][k];
return e[index];
}
void add(int&a, int&b){
++k;
N[a].push_back(b);
}
};
int main(){
fstream f ("lca.in");
fstream g("lca.out");
int n, m,x;
f >> n >> m;
tree t(1);
for (int i = 2; i <= n; ++i){
f >> x;
t.add(x, i);
}
t.preprocess();
for (int i = 0; i < m; ++i){
f >> n >> x;
g << t.lca(n, x) << endl;
}
}