Pagini recente » Cod sursa (job #2158584) | Cod sursa (job #2240855) | Cod sursa (job #711109) | Cod sursa (job #2665375) | Cod sursa (job #1329618)
#include <fstream>
#include <vector>
#define Lmax 19
#define Nmax 100100
using namespace std;
vector <int> Tree[Nmax];
vector < pair<int, int> > Euler;
int N, First[Nmax];
class RangeMinimumQuery {
private:
int size, Log2[Nmax << 1], Rmq[Lmax][Nmax << 1];
public:
void init(int Size) {
size = Size;
for(int i = 2; i <= size; i++)
Log2[i] = Log2[size >> 1] + 1;
for(int i = 1; i <= size; i++)
Rmq[0][i] = i - 1;
}
void process() {
int i, j;
for(i = 1; i <= Log2[size]; i++)
for(j = 1; j <= size - (1 << i) + 1; j++)
if(Euler[Rmq[i - 1][j]].second < Euler[Rmq[i - 1][j + (1 << (i-1))]].second)
Rmq[i][j] = Rmq[i - 1][j];
else
Rmq[i][j] = Rmq[i - 1][j + (1 << (i-1))];
}
void update(int index, int value) {
Rmq[0][index] = value;
}
int query(int x, int y) {
x = First[x];
y = First[y];
if(x > y)
swap(x, y);
int log2 = Log2[y - x + 1];
if(Euler[Rmq[log2][x]].second < Euler[Rmq[log2][y - (1 << log2) + 1]].second)
return Euler[Rmq[log2][x]].first;
else
return Euler[Rmq[log2][y - (1 << log2) + 1]].first;
}
} rmq;
void Dfs(int node, int level) {
First[node] = Euler.size();
Euler.push_back(make_pair(node, level));
for(int i = 0; i < Tree[node].size(); i++) {
Dfs(Tree[node][i], level + 1);
Euler.push_back(make_pair(node, level));
}
}
int main() {
int i, x, y, queries;
ifstream in("lca.in");
ofstream out("lca.out");
in >> N >> queries;
for(i = 2; i <= N; i++) {
in >> x;
Tree[x].push_back(i);
}
Dfs(1, 0);
rmq.init(Euler.size());
rmq.process();
while(queries--) {
in >> x >> y;
out << rmq.query(x, y) << '\n';
}
in.close();
out.close();
return 0;
}