Pagini recente » Cod sursa (job #584802) | Cod sursa (job #654801) | Cod sursa (job #305561) | Cod sursa (job #654292) | Cod sursa (job #1087608)
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
#define NMAX 100005
#define NMAX2 200005
#define LogNMAX2 20
#define minim(a,b) ((a<b)?(a):(b))
#define Enode first
#define Edepth second
int N,Q;
int FirstInEuler[NMAX];
int SparseTable[NMAX2][LogNMAX2];
int Log[LogNMAX2];
vector < int > G[NMAX];
vector < pair < int , int > > Euler;
void DFS(int node, int depth)
{
Euler.push_back(make_pair(node,depth));
FirstInEuler[node] = Euler.size() - 1;
for(vector < int > :: iterator it = G[node].begin(); it != G[node].end(); ++it)
{
DFS(*it,depth+1);
Euler.push_back(make_pair(node,depth));
}
}
void ContructRMQ()
{
Log[0] = 1;
for(int i=1;i<Euler.size();i++)
{
SparseTable[i][0] = i;
Log[i] = Log[i-1] << 1;
}
int i,j, minUntilNowPos,minOnSecondSegmentPos;
for(j=1; Log[j] <Euler.size(); j++)
for(i=1;i + Log[j] <= Euler.size();i++)
{
minUntilNowPos = SparseTable[i][j-1];
minOnSecondSegmentPos = SparseTable[i + Log[j-1]][j-1];
if(Euler[minUntilNowPos].Edepth<=Euler[minOnSecondSegmentPos].Edepth)
SparseTable[i][j] = minUntilNowPos;
else
SparseTable[i][j] = minOnSecondSegmentPos;
}
}
int LCA(int i, int j)
{
int x,y;
x = FirstInEuler[i];
y = FirstInEuler[j];
if(x>y)
swap(x,y);
int k = (int) log2(double(y-x+1));
int minOnFirstSegmentPos,minOnSecondSegmentPos;
minOnFirstSegmentPos = SparseTable[x][k];
minOnSecondSegmentPos = SparseTable[y - Log[k] + 1][k];
if(Euler[minOnFirstSegmentPos].Edepth <= Euler[minOnSecondSegmentPos].Edepth)
return Euler[minOnFirstSegmentPos].Enode;
return Euler[minOnSecondSegmentPos].Enode;
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d%d",&N,&Q);
int x,y;
for(int i=2;i<=N;i++)
{
scanf("%d",&x);
G[x].push_back(i);
}
Euler.push_back(make_pair(0,0));
DFS(1,0);
ContructRMQ();
for(int i=1;i<=Q;i++)
{
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
return 0;
}