Pagini recente » Cod sursa (job #1606418) | Cod sursa (job #1425072) | Cod sursa (job #461230) | Cod sursa (job #2514919) | Cod sursa (job #1525217)
#include <fstream>
#include <vector>
#define NMax 100010
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int nodes, queries, eulPath[2*NMax], k, lvl[2*NMax], firstOc[NMax], rmq[18][2*NMax], lg[2*NMax];
bool mark[NMax];
vector<int> tree[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 level)
{
k++;
eulPath[k] = node;
lvl[k] = level;
for (vector<int>::iterator it = tree[node].begin(); it != tree[node].end(); it++) {
DFS(*it, level+1);
eulPath[++k] = node;
lvl[k] = level;
}
}
void preprocRMQ()
{
for (int i=2; i<=k; i++)
lg[i] = lg[i/2] + 1;
for (int i=1; i<=lg[k]; i++) {
int power = 1<<(i-1);
for (int j=1; j <= k - power; j++) {
rmq[i][j] = rmq[i-1][j];
if (lvl[ rmq[i][j] ] > lvl[ rmq[i-1][j + power] ])
rmq[i][j] = rmq[i-1][j + power];
}
}
}
int main()
{
f>>nodes>>queries;
int node;
for (int i=2; i<=nodes; i++) {
f>>node;
tree[node].push_back(i);
}
DFS(1, 1);
for (int i=1; i<=k; i++) {
int crtNode = eulPath[i];
if (!mark[crtNode]) {
firstOc[crtNode] = i;
mark[crtNode] = true;
}
}
for (int i=1; i<=k; i++)
rmq[0][i] = i;
preprocRMQ();
int node1, node2;
for (int i=1; i<=queries; i++) {
f>>node1>>node2;
int left = getMin(firstOc[node1], firstOc[node2]);
int right = getMax(firstOc[node1], firstOc[node2]);
int llg = lg[right - left];
if (lvl[rmq[llg][left]] < lvl[rmq[llg][right - (1<<llg) + 1]])
g<<eulPath[rmq[llg][left]]<<"\n";
else
g<<eulPath[rmq[llg][right - (1<<llg) + 1]]<<"\n";
}
return 0;
}