Pagini recente » Cod sursa (job #2216199) | Cod sursa (job #362514) | Cod sursa (job #2069602) | Cod sursa (job #1354503) | Cod sursa (job #2466799)
#include <fstream>
#include <vector>
using namespace std;
vector <int> a[100005];
int x,y,n,m,q,k,p,Min1,Min2;
int pw[100],ln[200005],v[200005],poz[400005][32],e[200005],lv[100005],viz[100005];
void dfs(int start, int level)
{int i;
viz[start]=++n;
e[n]=start;
lv[start]=level;
for(i=0;i<a[start].size();i++)
if(!viz[a[start][i]])
{
dfs(a[start][i],level+1);
e[++n]=start;
}
}
void RMQ()
{int i,j;
pw[0]=1;
for(i=1;i<=30;i++)
pw[i]=pw[i-1]*2;
k=0;
for(i=1;i<=n;i++)
if(i==pw[k])
{
ln[i]=k;
k++;
}
else
ln[i]=k-1;
for(i=1;i<=n;i++)
poz[i][0]=i;
for(j=1;j<=ln[n];j++)
for(i=1;i<=n;i++)
if(v[ poz[i][j-1] ] < v[ poz[i+pw[j-1]][j-1] ])
poz[i][j]=poz[i][j-1];
else
poz[i][j]=poz[i+pw[j-1]][j-1];
}
int main()
{
ifstream f("lca.in");
ofstream g("lca.out");
///lca(x,y)=nodul cu cel mai mic nivel situat intre
///prima aparitie a lui x si prima aparitie a lui y
///in parcurgerea df a arborelui
int i;
f>>m>>q;
for(i=2;i<=m;i++)
{
f>>x;
a[x].push_back(i);
}
dfs(1,1);
for(i=1;i<=n;i++)
v[i]=lv[e[i]];
RMQ();
for(i=1;i<=q;i++)
{
f>>x>>y;
x=viz[x];
y=viz[y];
if(x>y)
swap(x,y);
k=y-x;
k=ln[k];
Min1=v[poz[x][k]];
p=y-x-pw[k]+1;
Min2=v[poz[x+p][k]];
if(Min1<Min2)
g<<e[poz[x][k]]<<'\n';
else
g<<e[poz[x+p][k]]<<'\n';
}
return 0;
}