Pagini recente » Cod sursa (job #2204103) | Cod sursa (job #927326) | Cod sursa (job #898335) | Cod sursa (job #601337) | Cod sursa (job #1163935)
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
const int NIL = -1;
template<class Type, class Compare>
class RMQ {
public:
RMQ(const vector<Type> &_objects, Compare _compare):
objects(_objects),
compare(_compare),
log2(int(_objects.size()) + 1, -1),
data(vector< vector<int> >()) {
log2[1] = 0;
for (int i = 2; i <= Size(); ++i)
log2[i] = log2[i / 2] + 1;
data = vector< vector<int> >(log2[Size()] + 1, vector<int>());
data[0] = vector<int>(Size());
for (int i = 0; i < Size(); ++i)
data[0][i] = i;
for (int step = 1; step < int(data.size()); ++step) {
data[step] = vector<int>(Size() - (1 << step) + 1);
for (int i = 0; i + (1 << step) - 1 < Size(); ++i) {
if (compare(objects[data[step - 1][i]], objects[data[step - 1][i + (1 << (step - 1))]]))
data[step][i] = data[step - 1][i];
else
data[step][i] = data[step - 1][i + (1 << (step - 1))];
}
}
}
int Size() const {
return int(objects.size());
}
Type Object(const int index) const {
return objects[index];
}
int QueryIndex(const int from, const int to) const {
int step = log2[to - from + 1];
if (compare(objects[data[step][from]], objects[data[step][to - (1 << step) + 1]]))
return data[step][from];
else
return data[step][to - (1 << step) + 1];
}
private:
vector<Type> objects;
Compare compare;
vector<int> log2;
vector< vector<int> > data;
};
vector< vector<int> > Tree;
int V, Root, Q;
vector<int> Levels, Euler, First;
class Compare {
public:
int operator()(const int a, const int b) const {
return Levels[a] < Levels[b];
}
};
void DFS(const int x) {
First[x] = int(Euler.size());
Euler.push_back(x);
for (vector<int>::const_iterator y = Tree[x].begin(); y != Tree[x].end(); ++y) {
Levels[*y] = Levels[x] + 1;
DFS(*y);
Euler.push_back(x);
}
}
void Preprocess() {
Levels = First = vector<int>(V, -1);
Euler = vector<int>();
Levels[Root] = 0;
DFS(Root);
}
inline void AddEdge(const int from, const int to) {
Tree[from].push_back(to);
}
int main() {
ifstream cin("lca.in");
ofstream cout("lca.out");
cin >> V >> Q;
Tree = vector< vector<int> >(V, vector<int>());
Root = 0;
for (int x = 2; x <= V; ++x) {
int y;
cin >> y;
AddEdge(y - 1, x - 1);
}
Preprocess();
RMQ<int, Compare> rmq = RMQ<int, Compare>(Euler, Compare());
for (; Q > 0; --Q) {
int x, y;
cin >> x >> y;
if (First[y - 1] < First[x - 1])
swap(x, y);
cout << rmq.Object(rmq.QueryIndex(First[x - 1], First[y - 1])) + 1 << "\n";
}
cin.close();
cout.close();
return 0;
}