Pagini recente » Cod sursa (job #324570) | Cod sursa (job #2049402)
#include <bits/stdc++.h>
#define MAX_N 100000
#define MAX_LOG 17
using namespace std;
FILE *f, *g;
int k;
int n, q;
int first[MAX_N + 1];
int nodul[MAX_N * 2 + 1];
int rmq[MAX_N * 2 + 1][MAX_LOG + 1];
int poz[MAX_N * 2 + 1][MAX_LOG + 1];
int edg;
int lst[MAX_N + 1];
int urm[MAX_N + 1];
int nod[MAX_N + 1];
void add(int a, int b)
{
edg ++;
nod[edg] = b;
urm[edg] = lst[a];
lst[a] = edg;
}
void readFile()
{
f = fopen("lca.in", "r");
fscanf(f, "%d%d", &n, &q);
int i;
int nr;
for(i = 2; i <= n; i ++)
{
fscanf(f, "%d", &nr);
add(nr, i);
}
}
int depth;
void dfs(int a)
{
depth ++;
if(first[a] == 0)
first[a] = k + 1;
++ k;
rmq[k][0] = depth;
poz[k][0] = k;
nodul[k] = a;
int p, u;
for(p = lst[a]; p != 0; p = urm[p])
{
dfs(nod[p]);
++ k;
rmq[k][0] = depth;
poz[k][0] = k;
nodul[k] = a;
}
depth --;
}
void RMQ()
{
int i, j;
int p, p2;
for(j = 1; j <= MAX_LOG; j ++)
{
int p = (1 << (j - 1));
int p2 = (1 << j);
for(i = 1; i + p2 - 1 <= k; i ++)
{
if(rmq[i][j - 1] < rmq[i + p][j - 1])
{
rmq[i][j] = rmq[i][j - 1];
poz[i][j] = poz[i][j - 1];
}
else
{
rmq[i][j] = rmq[i + p][j - 1];
poz[i][j] = poz[i + p][j - 1];
}
}
}
}
int lg[MAX_N + 1];
void getLg()
{
lg[1] = 0;
int i;
for(i = 2; i <= n; i ++)
lg[i] = lg[i >> 1] + 1;
}
void preCalc()
{
dfs(1);
getLg();
RMQ();
}
int getMin(int st, int dr)
{
if(st > dr)
swap(st, dr);
int len = dr - st + 1;
int p2 = lg[len];
int diff = len - (1 << p2);
return min(rmq[st][p2], rmq[st + diff][p2]) == rmq[st][p2] ? nodul[poz[st][p2]] : nodul[poz[st + diff][p2]];
}
void ansQues()
{
g = fopen("lca.out", "w");
int a, b;
while(q > 0)
{
fscanf(f, "%d%d", &a, &b);
fprintf(g, "%d\n", getMin(first[a], first[b]));
q --;
}
fclose(f);
fclose(g);
}
int main()
{
readFile();
preCalc();
ansQues();
return 0;
}