Pagini recente » Cod sursa (job #968001) | Cod sursa (job #2115790) | Cod sursa (job #323339) | Cod sursa (job #1561989) | Cod sursa (job #2315236)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int k,p;
ifstream fi("lca.in");
ofstream fo("lca.out");
vector <int> D[100001];
int n,q;
int ne,E[300001];
int FIRST[100001];
int LEVEL[100001];
int T[300001][20];
int query(int st, int dr)
/// returneaza varful de nivel minim care apare
/// intre E[st] si E[dr];
{
if (st>dr)
swap(st,dr);
int rez;
rez=E[st];
for (int i=k;i>=0;i--)
if (st+(1<<i)-1<=dr)
{
if (LEVEL[rez]>LEVEL[T[st][i]])
rez=T[st][i];
st=st+(1<<i);
}
return rez;
}
void lvl(int nod,int level)
{
LEVEL[nod]=level;
vector <int> :: iterator it;
for (it=D[nod].begin(); it!=D[nod].end(); it++)
lvl(*it,level+1);
}
void euler(int nod)
{
vector <int> :: iterator it;
if (D[nod].size()==0)
{
ne++;
E[ne]=nod;
if(FIRST[nod]==0)
FIRST[nod]=ne;
}
else
{
ne++;
E[ne]=nod;
if(FIRST[nod]==0)
FIRST[nod]=ne;
for (it=D[nod].begin(); it!=D[nod].end(); it++)
{
euler(*it);
ne++;
E[ne]=nod;
if(FIRST[nod]==0)
FIRST[nod]=ne;
}
}
}
int main()
{
fi>>n>>q;
for(int i=2; i<=n; i++)
{
int a;
fi>>a;
D[a].push_back(i);
}
euler(1);
lvl(1,0);
/// se construieste sparse table pentru E
/// k este indicele ultimei coloane din T
k=0;
p=1;
while (p*2<=ne)
{
k++;
p=p*2;
}
/// se construieste sparse table
for (int i=1; i<=ne; i++)
T[i][0]=E[i];
for (int j=1; j<=k; j++)
for (int i=1; i<=ne-(1<<j)+1; i++)
if (LEVEL[T[i][j-1]]<LEVEL[T[i+(1<<(j-1))][j-1]])
T[i][j]=T[i][j-1];
else
T[i][j]=T[i+(1<<(j-1))][j-1];
/// se raspunde la intrebari
for (int qu=1; qu<=q; qu++)
{
int a,b;
fi>>a>>b;
fo<<query(FIRST[a],FIRST[b])<<"\n";
}
fi.close();
fo.close();
return 0;
}