Pagini recente » Istoria paginii runda/ce_concurs | Cod sursa (job #1832344) | Cod sursa (job #1521566) | Cod sursa (job #758154) | Cod sursa (job #739848)
Cod sursa(job #739848)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
#define dim 100001
int euler[dim*2],nivel[dim*2];
int n,m,lungime=0;
int rmq[20][dim*2];
vector <int> fii[dim];
void Euler_si_Nivel(int nod)
{
nivel[nod]=++lungime;
euler[lungime]=nod;
int numarFii=fii[nod].size();
for(int i=0;i<numarFii;i++)
{
Euler_si_Nivel(fii[nod][i]);
euler[++lungime]=nod;
}
}
void RMQ()
{
for(int i=1;i<lungime;i++)
rmq[0][i]=euler[i];
for(int i=1;(1<<i)<=lungime;i++)
{
for(int j=1;j<=lungime-(1<<i)+1;++j)
rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]);
}
}
int lca(int x,int y)
{
int nx=nivel[x];
int ny=nivel[y];
if (nx>ny) swap(nx,ny);
int i;
for(i=1;(1<<i)<=(ny-nx+1);i++)
i--;
return min(rmq[i][nx],rmq[i][y-(1<<i)+1]);
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
fin>>n;
fin>>m;
int x,y;
for(int i=2;i<=n;i++)
{
fin>>x;
fii[x].push_back(i);
}
Euler_si_Nivel(1);
RMQ();
for(int i=1;i<=m;i++)
{
fin>>x;
fin>>y;
fout<<lca(x,y)<<"\n";
}
fin.close();
fout.close();
return 0;
}