Pagini recente » Cod sursa (job #405669) | Cod sursa (job #1502020) | Cod sursa (job #483676) | Cod sursa (job #483392) | Cod sursa (job #852789)
Cod sursa(job #852789)
#include <cstdio>
const int MAX_N(100001);
int n, m;
int level [MAX_N];
int log [MAX_N << 1];
int rmq [18] [MAX_N << 1], index(1);
int start [MAX_N];
struct list
{
int node;
struct list *next;
} *graph [MAX_N];
inline void add (int x, int y)
{
struct list *new_edge(new struct list);
new_edge->node = y;
new_edge->next = graph[x];
graph[x] = new_edge;
}
void DepthFirstSearch (int node, int depth)
{
start[node] = index;
rmq[0][index] = node;
++index;
level[node] = depth;
for (struct list *iterator(graph[node]) ; iterator ; iterator = iterator->next)
{
DepthFirstSearch(iterator->node,depth + 1);
rmq[0][index] = node;
++index;
}
}
inline int min (int a, int b)
{
return level[a] < level[b] ? a : b;
}
inline void initialize (void)
{
--index;
int i, j;
for (i = 2 ; i <= index ; ++i)
log[i] = log[i >> 1] + 1;
for (i = 1 ; i <= log[index] ; ++i)
for (j = 1 ; j <= index - (1 << i) + 1 ; ++j)
rmq[i][j] = min(rmq[i - 1][j],rmq[i - 1][j + (1 << (i - 1))]);
}
inline void swap (int &a, int &b)
{
int temp(a);
a = b;
b = temp;
}
inline int RangeMinimumQuery (int x, int y)
{
int cardinal(y - x + 1);
return min(rmq[log[cardinal]][x],rmq[log[cardinal]][y - (1 << log[cardinal]) + 1]);
}
inline int LowestCommonAncestor (int x, int y)
{
x = start[x];
y = start[y];
if (x > y)
swap(x,y);
return RangeMinimumQuery(x,y);
}
int main (void)
{
std::freopen("lca.in","r",stdin);
std::freopen("lca.out","w",stdout);
std::scanf("%d %d",&n,&m);
for (int counter(2), father ; counter <= n ; ++counter)
{
std::scanf("%d",&father);
add(father,counter);
}
DepthFirstSearch(1,0);
initialize();
for (int counter(0), x, y ; counter < m ; ++counter)
{
std::scanf("%d %d",&x,&y);
std::printf("%d\n",LowestCommonAncestor(x,y));
}
std::fclose(stdin);
std::fclose(stdout);
return 0;
}