Pagini recente » Cod sursa (job #631861) | Cod sursa (job #2985268) | Cod sursa (job #3141797) | Cod sursa (job #2459555) | Cod sursa (job #996017)
Cod sursa(job #996017)
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
class Tree {
public:
Tree(const int V = 0, const int root = 0) {
this->V = V;
this->root = root;
G = vector< vector<int> >(V, vector<int>());
}
int Size() const {
return V;
}
vector<int> &Adjacent(const int x) {
return G[x];
}
void AddEdge(const int x, const int y) {
G[x].push_back(y);
G[y].push_back(x);
}
vector<int> GetNodeLevels() const {
vector<int> levels = vector<int>(V, -1);
levels[root] = 0;
LevelDFS(root, levels);
return levels;
}
vector<int> GetEulerOrder() const {
vector<int> euler;
EulerDFS(root, NIL, euler);
return euler;
}
private:
static const int NIL = -1;
int V, root;
vector< vector<int> > G;
void LevelDFS(const int x, vector<int> &levels) const {
for (const auto &y: G[x]) {
if (levels[y] == -1) {
levels[y] = levels[x] + 1;
LevelDFS(y, levels);
}
}
}
void EulerDFS(const int x, const int father, vector<int> &euler) const {
euler.push_back(x);
for (const auto &y: G[x]) {
if (y != father) {
EulerDFS(y, x, euler);
euler.push_back(x);
}
}
}
};
template<class Type>
class RMQ {
public:
RMQ(const vector<Type> &values) {
this->values = values;
size = int(values.size());
log2 = vector<int>(size + 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 <= log2[size]; ++step) {
data[step] = vector<int>(size - (1 << step) + 1);
for (int i = 0; i + (1 << step) <= size; ++i) {
if (values[data[step - 1][i]] < values[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 Query(const int left, const int right) const {
int step = log2[right - left + 1];
if (values[data[step][left]] < values[data[step][right - (1 << step) + 1]])
return data[step][left];
else
return data[step][right - (1 << step) + 1];
}
private:
int size;
vector<int> log2;
vector< vector<int> > data;
vector<Type> values;
};
int main() {
ifstream cin("lca.in");
ofstream cout("lca.out");
int v, q;
cin >> v >> q;
Tree T = Tree(v, 0);
for (int x = 2; x <= v; ++x) {
int y;
cin >> y;
T.AddEdge(x - 1, y - 1);
}
vector<int> euler = T.GetEulerOrder(), first = vector<int>(v, -1), levels = T.GetNodeLevels();
vector<int> eulerLevels = vector<int>(int(euler.size()));
for (int i = 0; i < int(euler.size()); ++i) {
if (first[euler[i]] == -1)
first[euler[i]] = i;
eulerLevels[i] = levels[euler[i]];
}
RMQ<int> rmq = RMQ<int>(eulerLevels);
for (; q > 0; --q) {
int x, y;
cin >> x >> y;
if (first[y - 1] < first[x - 1])
swap(x, y);
cout << euler[rmq.Query(first[x - 1], first[y - 1])] + 1 << "\n";
}
cin.close();
cout.close();
return 0;
}