Pagini recente » Cod sursa (job #2477173) | Cod sursa (job #368361) | Cod sursa (job #2726082) | Cod sursa (job #2032475) | Cod sursa (job #2608136)
//
// main.cpp
// lca
//
// Created by Ciprian Ionescu on 4/30/20.
// Copyright © 2020 CIP.FUN. All rights reserved.
//
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <queue>
#include <stack>
#define MAX_N 100000
#define MAX_LOG 18
using std::cin;
using std::cout;
template <typename T, typename C = T>
struct Node {
T node;
Node *next;
C weight;
};
template <typename T, size_t N, size_t M>
class Graph {
public:
size_t size;
void add(const T& x, const T& y) {
_nodes[++size].node = y;
_nodes[size].next = _list[x];
_list[x] = &_nodes[size];
}
void add_weighted(const T& x, const T& y, const T& weight) {
_nodes[++size].node = y;
_nodes[size].weight = weight;
_nodes[size].next = _list[x];
_list[x] = &_nodes[size];
}
Node<T>& get_node(const T& x) {
return *_list[x];
}
bool visited(const T& x) {
return _visited[x];
}
void visit(const T& x) {
_visited[x] = true;
}
void reset() {
for (auto &it : _visited) it = false;
}
private:
std::array<Node<T>, M> _nodes;
std::array<Node<T>*, N> _list;
std::array<bool, N> _visited;
};
int ti[1 + MAX_N], to[1 + MAX_N], tm, t[MAX_LOG][1 + MAX_N];
template <typename T, size_t N, size_t M>
void ancestor_tree(Graph<T, N, M>& g, const T& x) {
g.visit(x);
ti[x] = ++tm;
Node<T>* p = &g.get_node(x);
while (p) {
if (!g.visited(p->node)) {
ancestor_tree(g, p->node);
t[0][p->node] = x;
}
p = p->next;
}
to[x] = ++tm;
}
int lca(int x, int y) {
if (ti[x] <= ti[y] && to[y] <= to[x])
return x;
int step = MAX_LOG - 1;
while (step >= 0) {
const int s = t[step][x];
if (s != 0 && ((ti[s] > ti[y]) || (to[y] > to[s])))
x = s;
step--;
}
return t[0][x];
}
Graph<int, 1 + MAX_N, 1 + MAX_N> g;
int main(int argc, const char * argv[]) {
std::ifstream fin("lca.in");
std::ofstream fout("lca.out");
int n, m;
fin >> n >> m;
for (auto i = 2 ; i <= n ; i++) {
int x;
fin >> x;
g.add(x, i);
}
ancestor_tree(g, 1);
for (auto i = 1 ; (1 << i) <= n ; i++) {
for (auto j = 1 ; j <= n ; j++)
t[i][j] = t[i - 1][t[i - 1][j]];
}
for (auto i = 1 ; i <= m ; i++) {
int x, y;
fin >> x >> y;
fout << lca(x, y) << '\n';
}
return 0;
}