Pagini recente » Cod sursa (job #1680722) | Cod sursa (job #692013) | Cod sursa (job #2889623) | Monitorul de evaluare | Cod sursa (job #3309178)
#include <fstream>
#include <vector>
#include <algorithm>
void buildEulerRepresentation(int node, const std::vector<std::vector<int>> &adjacent, std::vector<int> &eulerRepresentation, std::vector<int> &level)
{
eulerRepresentation.push_back(node);
for (int neighbor: adjacent[node])
{
level[neighbor] = level[node] + 1;
buildEulerRepresentation(neighbor, adjacent, eulerRepresentation, level);
eulerRepresentation.push_back(node);
}
}
int main()
{
std::ifstream inFile("lca.in");
int n, m;
inFile >> n >> m;
std::vector<std::vector<int>> adjacent(n + 1);
for (int node = 2; node <= n; ++node)
{
int parent;
inFile >> parent;
adjacent[parent].push_back(node);
}
std::vector<int> eulerRepresentation, level(n + 1);
eulerRepresentation.reserve(2 * n - 1);
buildEulerRepresentation(1, adjacent, eulerRepresentation, level);
std::vector<int> firstPosition(n + 1, -1);
for (int i = 0; i < eulerRepresentation.size(); ++i)
{
if (firstPosition[eulerRepresentation[i]] == -1)
firstPosition[eulerRepresentation[i]] = i;
}
int maxExponent = 18;
std::vector<std::vector<int>> sparseTable(maxExponent);
sparseTable[0] = eulerRepresentation;
for (int i = 1; i < maxExponent; ++i)
{
if ((1 << i) > eulerRepresentation.size())
break;
sparseTable[i].resize(eulerRepresentation.size() - (1 << i) + 1);
for (int j = 0; j + (1 << i) -1 < eulerRepresentation.size(); ++j)
{
if (level[sparseTable[i - 1][j]] < level[sparseTable[i - 1][j + (1 << (i - 1))]])
sparseTable[i][j] = sparseTable[i - 1][j];
else
sparseTable[i][j] = sparseTable[i - 1][j + (1 << (i - 1))];
}
}
std::vector<int> maxLength(eulerRepresentation.size() + 2);
int currentMaxLength = 0;
for (int i = 1; i < maxLength.size(); ++i)
{
if ((1 << (currentMaxLength + 1)) <= i)
++currentMaxLength;
maxLength[i] = currentMaxLength;
}
std::ofstream outFile("lca.out");
while (m--)
{
int node1, node2;
inFile >> node1 >> node2;
if (node1 == node2)
{
outFile << node1 << '\n';
continue;
}
int first = std::min(firstPosition[node1], firstPosition[node2]), second = std::max(firstPosition[node1], firstPosition[node2]);
int length = second - first + 1, answer;
if (level[sparseTable[maxLength[length]][first]] < level[sparseTable[maxLength[length]][second - (1 << maxLength[length]) + 1]])
answer = sparseTable[maxLength[length]][first];
else
answer = sparseTable[maxLength[length]][second - (1 << maxLength[length]) + 1];
outFile << answer << '\n';
}
inFile.close();
outFile.close();
return 0;
}