Pagini recente » Cod sursa (job #1851653) | Cod sursa (job #1623207) | Cod sursa (job #1331343) | Cod sursa (job #356232) | Cod sursa (job #1184952)
#include<fstream>
#include<vector>
#include<bitset>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m,a[100005],Euler[200005],lg,nivel[200005],puteri[25],logaritm[200005];
int mat[200005][20],aparitii[100005];
vector<int>v[100005];
bitset<100005>viz;
inline void DFS(int x,int niv)
{
int i,len;
nivel[x]=niv;
len=v[x].size();
for (i=0;i<len;i++)
DFS(v[x][i],niv+1);
}
inline void ParcurgereEuler(int x)
{
int i,len;
if (!viz[x]) {aparitii[x]=lg+1;viz[x]=1;}
len=v[x].size();
for (i=0;i<len;i++)
{
Euler[++lg]=x;
ParcurgereEuler(v[x][i]);
}
Euler[++lg]=x;
}
inline void RMQ()
{
int i,aux,put;
mat[lg][0]=Euler[lg];
for (i=lg-1;i>=1;i--)
{
if (nivel[Euler[i]]<nivel[Euler[i+1]]) mat[i][0]=Euler[i];
else mat[i][0]=Euler[i+1];
aux=lg-i;
put=1;
while (puteri[put]<=aux)
{
if (nivel[mat[i][put-1]]<nivel[mat[i+puteri[put-1]][put-1]]) mat[i][put]=mat[i][put-1];
else mat[i][put]=mat[i+puteri[put-1]][put-1];
put++;
}
}
logaritm[2]=1;
for (i=3;i<=200000;i++)
logaritm[i]=logaritm[i>>1]+1;
}
inline void Rezolva()
{
int i,x,y,aux,st,dr;
while (m--)
{
fin>>x>>y;
st=min(aparitii[x],aparitii[y]);
dr=max(aparitii[x],aparitii[y]);
aux=dr-st;
if (nivel[mat[st][logaritm[aux]]]<nivel[mat[dr-puteri[logaritm[aux]]][logaritm[aux]]])
fout<<mat[st][logaritm[aux]];
else fout<<mat[dr-puteri[logaritm[aux]]][logaritm[aux]];
fout<<"\n";
}
}
int main()
{
int i;
fin>>n>>m;
for (i=1;i<=n-1;i++)
{
fin>>a[i];
v[a[i]].push_back(i+1);
}
puteri[0]=1;
puteri[1]=2;
for (i=1;i<=22;i++)
puteri[i]=puteri[i-1]<<1;
DFS(1,1);
ParcurgereEuler(1);
RMQ();
Rezolva();
fout<<"\n";
return 0;
}