Pagini recente » Cod sursa (job #1315560) | Cod sursa (job #3131639) | Cod sursa (job #990970) | Cod sursa (job #132919) | Cod sursa (job #1599495)
#include <fstream>
#include <vector>
#define NMax 100010
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int nodes, queries, RMQ[18][2 * NMax], lg[2 * NMax], euler[2 * NMax], firstOc[NMax], k, level[2 * NMax];
bool mark[NMax];
vector<int> G[NMax];
int getMin(int a, int b)
{
if (a < b)
return a;
return b;
}
int getMax(int a, int b)
{
if (a > b)
return a;
return b;
}
void DFS(int node, int lvl)
{
mark[node] = true;
euler[++k] = node;
level[k] = lvl;
for (vector<int>::iterator it = G[node].begin(); it != G[node].end(); it++) {
mark[*it] = true;
DFS(*it, lvl + 1);
euler[++k] = node;
level[k] = lvl;
}
}
int main()
{
for (int i = 2; i <= 2 * NMax - 1; i++)
lg[i] = lg[i / 2] + 1;
f >> nodes >> queries;
int node;
for (int i = 2; i <= nodes; i++) {
f >> node;
G[node].push_back(i);
}
DFS(1, 0);
for (int i = 1; i <= k; i++) {
if (!firstOc[euler[i]])
firstOc[euler[i]] = i;
RMQ[0][i] = i;
}
for (int i = 1; i <= lg[k]; i++) {
for (int j = 1; j <= k - (1 << i) + 1; j++) {
if (level[RMQ[i - 1][j]] < level[RMQ[i - 1][j + (1 << (i - 1))]])
RMQ[i][j] = RMQ[i - 1][j];
else
RMQ[i][j] = RMQ[i - 1][j + (1 << (i-1))];
}
}
int n1, n2;
for (int i = 1; i <= queries; i++) {
f >> n1 >> n2;
int pos1 = getMin(firstOc[n1], firstOc[n2]);
int pos2 = getMax(firstOc[n1], firstOc[n2]);
int span = lg[pos2 - pos1 + 1];
if (level[RMQ[span][pos1]] < level[RMQ[span][pos2 - (1 << span) + 1]])
g << euler[RMQ[span][pos1]] << "\n";
else
g << euler[RMQ[span][pos2 - (1 << span) + 1]] << "\n";
}
return 0;
}