Pagini recente » Statistici Trifan Gabriela (trifan_gabriela) | Istoria paginii utilizator/cigodaruiulian | Rating Ko Bold (mr.kobold) | Rating Cirstea Bogdan-Ionut (Bogdan.Cirstea) | Cod sursa (job #2016008)
#include <fstream>
#include <vector>
using namespace std;
struct Node
{
int time = 0;
vector<int> sons;
vector<int> ancestors;
};
using Tree = vector<Node>;
const int kBuffCap = (1 << 16);
ifstream fin("lca.in");
ofstream fout("lca.out");
char NextChar()
{
static char buffer[kBuffCap];
static int buff_size = 0;
static int buff_index = kBuffCap;
if (buff_index >= buff_size) {
fin.read(buffer, kBuffCap);
buff_size = fin.gcount();
buff_index = 0;
}
return buffer[buff_index++];
}
int NextInt()
{
char ch;
do {
ch = NextChar();
} while (ch < '0' || ch > '9');
int num = 0;
while (ch >= '0' && ch <= '9') {
num = num * 10 + ch - '0';
ch = NextChar();
}
return num;
}
void Dfs(Tree &t, int node)
{
if (!t[node].ancestors.empty()) {
int father = t[node].ancestors[0];
int order = 0;
while (order < (int)t[father].ancestors.size()) {
int anc = t[father].ancestors[order];
t[node].ancestors.push_back(anc);
father = anc;
order += 1;
}
}
for (const auto &son : t[node].sons) {
Dfs(t, son);
}
static int time = 0;
t[node].time = ++time;
}
int FindLca(const Tree &t, int a, int b)
{
if (t[a].time > t[b].time) {
swap(a, b);
}
while (t[a].time < t[b].time) {
if (t[a].ancestors.size() == 1) {
a = t[a].ancestors[0];
}
for (size_t i = 1; i < t[a].ancestors.size(); ++i) {
int anc = t[a].ancestors[i];
if (t[anc].time > t[b].time) {
a = t[a].ancestors[i - 1];
break;
} else if (i + 1 == t[a].ancestors.size()) {
a = t[a].ancestors.back();
}
}
}
return a;
}
int main()
{
int nodes = NextInt();
int q = NextInt();
Tree tree(nodes);
for (int i = 1; i < nodes; ++i) {
int father = NextInt();
tree[i].ancestors.push_back(father - 1);
tree[father - 1].sons.push_back(i);
}
Dfs(tree, 0);
while (q--) {
int a = NextInt();
int b = NextInt();
auto res = FindLca(tree, a - 1, b - 1);
fout << res + 1 << "\n";
}
return 0;
}