Pagini recente » Cod sursa (job #1833857) | Cod sursa (job #2922963) | Cod sursa (job #1279570) | Cod sursa (job #1335951) | Cod sursa (job #739639)
Cod sursa(job #739639)
#include<fstream>
#include<vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
#define MAX 200100
int n, m, RMQ[20][MAX];
int euler[MAX], nivel[MAX];
vector<int> vec[MAX];
void dfs(int);
void rmq();
int query(int, int);
int main()
{
int a, b;
f>>n>>m; // read number of nodes and number of pairs
for(int i = 2; i <= n; ++i) // go through next n-1 numbers which represent every node except the root
{
f>>a; // read the node
vec[a].push_back(i); // create parent tree
}
dfs(1);
rmq();
for(int i = 1; i <= m; ++i) // solve lca's for pairs
{
f>>a>>b; // read pair of nodes
g<<query(a, b)<<"\n"; // write least common ancestor in output file
}
f.close();
g.close();
return 0;
}
void dfs(int nod)
{
int i;
euler[++euler[0]]=nod; // add current node to euler representation of tree
nivel[nod] = euler[0];
for(i = 0; i < (int)vec[nod].size(); ++i)
{
dfs(vec[nod][i]);
euler[++euler[0]] = nod;
}
}
void rmq()
{
// in rmq[i][j] we retain the minimal level between the positions (j, j + 2*i - 1) from the euler representation
for(int i = 1; i < euler[0]; ++i)
RMQ[0][i] = euler[i];
for(int i = 1; (1 << i) <= euler[0]; ++i)
for(int j = 1; j<= euler[0] - (1<<i) + 1; ++j)
RMQ[i][j] = min(RMQ[i-1][j], RMQ[i-1][j + (1 << (i-1))]);
}
int query(int a, int b)
{
int x, y, i;
x = nivel[a];
y = nivel[b];
if( x > y ) swap(x, y);
for( i = 1; (1 << i) <= (y-x+1); ++i);
--i;
return min(RMQ[i][x], RMQ[i][y - (1 << i) + 1]);
}