Pagini recente » Cod sursa (job #2459513) | Cod sursa (job #1352746) | Cod sursa (job #657864) | Cod sursa (job #263399) | Cod sursa (job #3036718)
#include <fstream>
#include <vector>
const int NMAX=500005;
const int LOG_MAX=25;
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int lca(int, int);
void dfs(int, int);
void construct_rmq();
int pt(int);
int query(int, int);
vector <int> v[NMAX];
int in[NMAX], lv[NMAX];
int rmq[NMAX][LOG_MAX];
int n, q, cnt;
int main()
{
int i, a, b;
fin>>n>>q;
for(i=2; i<=n; i++)
{
fin>>a;
v[i].push_back(a);
v[a].push_back(i);
}
dfs(1, 0);
construct_rmq();
for(i=1; i<=q; i++)
{
fin>>a>>b;
fout<<lca(a, b)<<'\n';
}
return 0;
}
void dfs(int nod, int lvl)
{
lv[nod]=lvl;
in[nod]=++cnt;
rmq[in[nod]][0]=nod;
for(auto i:v[nod])
{
if(!in[i])
{
dfs(i, lvl+1);
rmq[++cnt][0]=nod;
}
}
}
void construct_rmq()
{
int i, j;
for(i=1; (1<<i)<=cnt; i++)
{
for(j=i; j<=cnt; j++)
{
if(lv[rmq[j][i-1]]<lv[rmq[j-(1<<(i-1))][i-1]])
rmq[j][i]=rmq[j][i-1];
else rmq[j][i]=rmq[j-(1<<(i-1))][i-1];
}
}
}
int lca(int a, int b)
{
if(in[a]>in[b]) swap(a, b);
return query(in[a], in[b]);
}
int query(int st, int dr)
{
int pw=pt(dr-st+1);
if(lv[rmq[st+(1<<pw)-1][pw]]<lv[rmq[dr][pw]])
return rmq[st+(1<<pw)-1][pw];
return rmq[dr][pw];
}
int pt(int nr)
{
int p=0;
while((1<<p)<=nr) p++;
return p-1;
}