Pagini recente » Cod sursa (job #809447) | Cod sursa (job #2146599) | Cod sursa (job #2536024) | Cod sursa (job #2823054) | Cod sursa (job #3218206)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
struct RmqItem{
int nod;
int lvl;
};
int p_curent, p_start[200001], max_log, max_bit[200001];
vector<int> v[100001];
RmqItem rmq[200001][20];
void dfs(int nod, int lvl)
{
int i;
rmq[++p_curent][0] = {nod, lvl};
p_start[nod] = p_curent;
for(i = 0; i < v[nod].size(); i++)
{
int vecin = v[nod][i];
dfs(vecin, lvl + 1);
rmq[++p_curent][0] = {nod,lvl};
}
}
void calc_rmq()
{
int i,p;
for(p = 1; p <= max_log; p++)
{
for(i = 1; i <= p_curent; i++)
{
RmqItem st = rmq[i][p-1];
if(i + (1<<(p-1)) <= p_curent)
{
RmqItem dr = rmq[i + (1<<(p-1))][p-1];
if(st.lvl < dr.lvl)
{
rmq[i][p] = st;
}
else
{
rmq[i][p] = dr;
}
}
}
}
}
void calc_max_bit()
{
int i;
max_bit[1] = 0;
for(i = 2; i <= p_curent; i++)
{
max_bit[i] = max_bit[i/2] + 1;
}
}
int lca(int x, int y)
{
int pos_x = p_start[x];
int pos_y = p_start[y];
if(pos_x > pos_y){swap(pos_x, pos_y);}
int l = max_bit[pos_y - pos_x + 1];
RmqItem st = rmq[pos_x][l];
RmqItem dr = rmq[pos_y - (1<<l) + 1][l];
if(st.lvl < dr.lvl)
{
return st.nod;
}
else
{
return dr.nod;
}
}
int main()
{
int n,i,q,a,b;
f>>n>>q;
for(i = 2; i <= n; i++)
{
f>>a;
v[a].push_back(i);
}
p_curent = 0;
dfs(1, 1);
max_log = 32 - __builtin_clz(n) - 1;
calc_rmq();
calc_max_bit();
for(i = 1; i <= q; i++)
{
f>>a>>b;
g<<lca(a,b)<<'\n';
}
return 0;
}