Pagini recente » Cod sursa (job #2684272) | Cod sursa (job #819392) | Cod sursa (job #107134) | Cod sursa (job #668313) | Cod sursa (job #1537865)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int euler[200005],lev[100005],first[100005], log[200005], rmq[18][200005], nod[18][200005],cnt=0,n,m;
vector <int> v[100005];
void dfs (int x)
{
euler[++cnt]= x;
first[x]= cnt;
for( int i=0; i<v[x].size(); ++i )
{
lev[v[x][i]]= lev[x]+1;
dfs(v[x][i]);
euler[++cnt]= x;
}
}
int lca (int x,int y)
{
x= first[x];
y= first[y];
if (x>y ) swap (x,y);
int dif= y-x+1;
int p= log[dif];
if (rmq[p][x]< rmq[p][ y-(1<<p)+1 ] )
return nod[p][x];
return nod[p][ y-(1<<p)+1] ;
}
int main()
{
fin>>n>>m;
for(int i=2;i<=n;++i)
{
int el;
fin>>el;
v[el].push_back(i);
}
dfs(1);
for(int i=2;i<=cnt;++i)
log[i]=log[i/2]+1;
for(int i=1;i<=cnt;++i)
{
rmq[0][i]= lev[euler[i]];
nod[0][i]= euler[i];
}
for(int i=1; (1<<i)<=cnt; ++i )
for(int j=1; j+(1<<i)-1<=cnt;++j )
{
if( rmq[i-1][j] < rmq[i-1][j+(1<<(i-1))] )
{
rmq[i][j]= rmq[i-1][j];
nod[i][j]= nod[i-1][j];
}
else
{
rmq[i][j]= rmq[i-1][j+(1<<(i-1))];
nod[i][j]= nod[i-1][j+(1<<(i-1))];
}
}
while(m--)
{
int a, b;
fin >> a >> b;
fout << lca(a, b) << "\n";
}
return 0;
}