Pagini recente » Cod sursa (job #1550787) | Cod sursa (job #2378294) | Cod sursa (job #74078) | Cod sursa (job #887077) | Cod sursa (job #862178)
Cod sursa(job #862178)
#include<fstream>
#include<vector>
#define NMAX 100010
#define LGP 200020
#define KMAX 20
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector<int> a[NMAX];
int n, T, lg, tata[NMAX], ad[NMAX], mn[KMAX][LGP], pz[NMAX], b[LGP], apr[LGP];
void Citeste()
{
int i;
f>>n>>T;
for (i=2; i<=n; ++i)
{
f>>tata[i];
a[tata[i]].push_back(i);
}
}
void Parcurge_Euler(int nod, int nr)
{
int i;
ad[nod]=nr;
mn[0][++lg]=nod;
if (!pz[nod]) pz[nod]=lg;
for (i=0; i<a[nod].size(); ++i)
{
Parcurge_Euler(a[nod][i], nr+1);
mn[0][++lg]=nod;
if (!pz[nod]) pz[nod]=lg;
}
}
void RMQ()
{
int k=0, i, z, zp=1;
for (k=1; 1<<k<=lg; ++k)
{
z=1<<k;
for (i=z; i<=lg; i++)
if (ad[mn[k-1][i]]<ad[mn[k-1][i-zp]]) mn[k][i]=mn[k-1][i];
else mn[k][i]=mn[k-1][i-zp];
zp=z;
}
}
void Preprop()
{
int i, p=1;
apr[1]=1; b[1]=0; apr[2]=2; b[2]=1;
for (i=3; i<=lg; ++i)
if (apr[i-1]<<1==i) apr[i]=apr[i-1]<<1, b[i]=b[i-1]+1;
else apr[i]=apr[i-1], b[i]=b[i-1];
}
void Query()
{
int x, y, px, py, lung, m, nr=0, sol;
while (T--)
{
f>>x>>y;
px=pz[x];
py=pz[y];
if (px>py) swap(px, py);
lung=py-px+1; m=apr[lung]; nr=b[lung];
sol=mn[nr][py];
lung=lung-m; py-=m;
while (lung>0)
{
m=apr[lung]; nr=b[lung];
if (ad[sol]>ad[mn[nr][py]]) sol=mn[nr][py];
lung=lung-m; py-=m;
}
g<<sol<<"\n";
}
}
int main()
{
Citeste();
Parcurge_Euler(1, 0);
Preprop();
RMQ();
Query();
f.close();
g.close();
return 0;
}