Pagini recente » Cod sursa (job #875158) | Cod sursa (job #1192805) | Cod sursa (job #684330) | Cod sursa (job #47528) | Cod sursa (job #721397)
Cod sursa(job #721397)
#include <fstream>
#include <algorithm>
#include <vector>
#include <utility>
#define euler first
#define level second
using namespace std;
vector <int> tree[100001];
vector <pair <int, int> > eulerTree;
vector <int> log2;
int RMQ[100000][18], position[100001];
int minRMQ(int A, int B)
{
if(eulerTree[A].level < eulerTree[B].level)
return A;
return B;
}
void getEulerAndLevels(int node, int nodeLevel)
{
position[node] = eulerTree.size();
eulerTree.push_back(make_pair(node, nodeLevel));
if(tree[node].size())
{
for(int i = 0; i < tree[node].size(); ++i)
{
getEulerAndLevels(tree[node][i], nodeLevel + 1);
eulerTree.push_back(make_pair(node, nodeLevel));
}
}
}
int queryLowestCommonAncestor(int firstNode, int secondNode)
{
int firstPosition = position[firstNode];
int secondPosition = position[secondNode];
if(firstPosition > secondPosition)
swap(firstPosition, secondPosition);
int K = log2[secondPosition - firstPosition + 1];
return minRMQ(RMQ[firstPosition][K], RMQ[secondPosition - (1 << K)][K]);
}
void buildRMQ()
{
int N = eulerTree.size();
for(int i = 1; i <= N; ++i)
RMQ[i][0] = i;
for(int j = 1; (1 << j) <= N; ++j)
for(int i = 0; i + (1 << j) - 1 <= N; ++i)
RMQ[i][j] = minRMQ(RMQ[i][j - 1], RMQ[i + (1 << (j - 1))][j - 1]);
}
void buildLogarithm(int size)
{
log2.push_back(0);
log2.push_back(0);
for(int i = 2; i <= size; ++i)
log2.push_back(log2[i/2] + 1);
}
int main()
{
int N, M;
ifstream in("lca.in");
in >> N >> M;
for(int i = 2, temp; i <= N; ++i)
{
in >> temp;
tree[temp].push_back(i);
}
getEulerAndLevels(1, 0);
buildLogarithm(eulerTree.size());
buildRMQ();
ofstream out("lca.out");
for(int i = 0, a, b; i < M; ++i)
{
in >> a >> b;
out << eulerTree[queryLowestCommonAncestor(a, b)].euler << "\n";
}
in.close();
out.close();
return 0;
}