Pagini recente » Cod sursa (job #1103236) | Cod sursa (job #2701212) | Cod sursa (job #608372) | Cod sursa (job #2390427) | Cod sursa (job #1563917)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
vector <int> vecin[100001],nivelvect;
vector <pair <int,int> > ciclu;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,x,i,seen[100001],nivel[100001],a,rmq[18][100001],o,p,poz[100001];
int biggestpower(int b)
{
int p=1;
int k=0;
while (2*p<=b)
{
p=p*2;
k++;
}
return k;
}
int topower(int b, int power)
{
if (power==0) return 1;
for (int l=1;l<power;l++)
b=b*2;
return b;
}
void precalculations()
{
int maxpower=biggestpower(ciclu.size());
for (int i=1;i<=maxpower;i++)
for (int j=1;j<=ciclu.size()-topower(2,i)+1;j++)
rmq[i][j] = min( rmq[i-1][j] , rmq[i-1][j+topower(2,i-1)]);
}
void solve()
{
for (i=1;i<=m;i++)
{
f>>o>>p;
int pozO=poz[o]+1;
int pozP=poz[p]+1;
int help1=max(pozO,pozP); int help2=min(pozO,pozP); //sa fim siguri ca pozP > pozO doooh
pozO=help2; pozP=help1;
if (pozP-pozO==1) g<<ciclu[pozO-1].first<<" ";
int maxpower=biggestpower(pozP-pozO);
int sol=min(rmq[maxpower][pozO] , rmq[maxpower][pozP-topower(2,maxpower)+1]);
for(int j=poz[o];j<=poz[p];j++)
if (ciclu[j].second==sol)
{
g<<ciclu[j].first<<" ";
break;
}
}
}
void euler(int x)
{
ciclu.push_back(make_pair(x,nivel[x]));
if (poz[ciclu.back().first]==0)
{
poz[ciclu.back().first]=ciclu.size()-1;
}
if (!vecin[x].empty())
{
for(int i=0;i<vecin[x].size();i++)
{
int y=vecin[x][i];
nivel[y]=nivel[x]+1;
euler(y);
ciclu.push_back(make_pair(x,nivel[x]));
}
}
}
int main()
{
f>>n>>m;
for (i=2;i<=n;i++)
{
f>>x;
vecin[x].push_back(i);
}
nivel[1]=0;
euler(1);
for (i=0;i<ciclu.size();i++)
rmq[0][i+1]=ciclu[i].second;
precalculations();
solve();
return 0;
}