Pagini recente » Cod sursa (job #136037) | Cod sursa (job #2476637) | Cod sursa (job #833159) | Cod sursa (job #1486264) | Cod sursa (job #969660)
Cod sursa(job #969660)
#include <fstream>
#include <vector>
#define In "lca.in"
#define Out "lca.out"
#define Nmax 100002
#define Root 1
#define min(a,b) ((a)<(b)?(a):(b))
#define pb push_back
#define mp make_pair
#define PII pair< int , int >
using namespace std;
vector<int>Tree[Nmax];
vector < PII > Euler;
int RMQ[Nmax][18], n, N, M,pos[Nmax], Log2[2*Nmax];
ifstream f(In);
inline void Read()
{
f>>N>>M;
int i, X;
for(i = 2;i <= N; ++i)
{
f>>X;
Tree[X].pb(i);
}
}
inline void _Euler(const int _node,const int height)
{
pos[_node] = ++n;
Euler.pb(mp(_node,height));
vector<int>::iterator it;
for(it = Tree[_node].begin();it!=Tree[_node].end();++it)
{
_Euler(*it,height+1);
Euler.pb(mp(_node,height));
n++;
}
}
inline void _RMQ()
{
int i, j, p1, p2;
for(i = 1;i <= n; ++i)
RMQ[i][0] = i;
for(j = 1;(1<<j) <= n; ++j)
for(i = 1;i + (1<<(j-1))<= n; ++i)
{
p1 = RMQ[i][j-1];
p2 = RMQ[i+(1<<(j-1))][j-1];
if(Euler[p1].second < Euler[p2].second)
RMQ[i][j] = p1;
else
RMQ[i][j] = p2;
}
Log2[1] = 0;
for(i = 2;i <= n; ++i)
Log2[i] = Log2[i>>1]+1;
}
inline int Query(const int X,const int Y)
{
int D = Y-X+1,L, p1, p2;
L = Log2[D];
p1 = RMQ[X][L];
p2 = RMQ[X+D-(1<<L)][L];
if(Euler[p1].second < Euler[p2].second)
return Euler[p1].first;
return Euler[p2].first;
}
inline void Write()
{
int X, Y;
ofstream g(Out);
while(M--)
{
f>>X>>Y;
if(pos[X]>pos[Y])
swap(X,Y);
g<<Query(pos[X],pos[Y])<<"\n";
}
f.close();
g.close();
}
int main()
{
Read();
Euler.pb(mp(0,0));
_Euler(Root,0);
_RMQ();
Write();
return 0;
}