Pagini recente » Cod sursa (job #471719) | Cod sursa (job #296740) | Cod sursa (job #2224829) | Cod sursa (job #2436037) | Cod sursa (job #2798946)
#include <stdio.h>
#include <ctype.h>
// Program de Mircea Rebengiuc
// inceput pe 2021.11.12
#define MAXB (128 * 1024)
#define MAXN 100000
#define MAXEULER (2 * MAXN)
#define MAXM 2000000
#define NIL -1
#define MAXL 18
int depth[MAXN];
int first[MAXN];
int kids[MAXN];
int adj[MAXM];
int next[MAXN];
int euler[MAXEULER];
int sp;
int rmq[MAXL][MAXEULER];
int logcalc[MAXEULER + 1];
// euler tour
void getEuler( int root, int parrent ){
int i = kids[root];
first[root] = sp;
euler[sp++] = root;
while( i != NIL ){
depth[adj[i]] = 1 + depth[root];
getEuler(adj[i], root);
euler[sp++] = root;
i = next[i];
}
}
// rmq
void rmqInit( int n ){
int l = 1, p2 = 2, i;
for( i = 0 ; i < n ; i++ )
rmq[0][i] = euler[i];
for( p2 = 2 ; p2 <= n ; p2 *= 2 ){
for( i = 0 ; i < n + 1 - p2 ; i++ )
rmq[l][i] = depth[rmq[l - 1][i]] < depth[rmq[l - 1][i + (p2 >> 1)]] ? rmq[l - 1][i] : rmq[l - 1][i + (p2 >> 1)];
l++;
}
logcalc[1] = 0;
for( i = 2 ; i <= n ; i++ )
logcalc[i] = 1 + logcalc[i >> 1];
}
static inline void order2( int *a, int *b ){
int aux;
if( (*a) > (*b) ){
aux = *b;
*b = *a;
*a = aux;
}
}
int rmqQuery( int a, int b ){
order2(&a, &b);
int l = logcalc[b - a + 1], p2 = (1 << logcalc[b - a + 1]);
return depth[rmq[l][a]] < depth[rmq[l][b - l + 1]] ? rmq[l][a] : rmq[l][b - p2 + 1];
}
// fast i/o
FILE *fin, *fout;
char ibuf[MAXB];
int ibp = MAXB - 1;
static inline int bgetc(){
if( (ibp = ((ibp + 1) & (MAXB - 1))) == 0 )
fread(ibuf, sizeof(char), MAXB, fin);
return ibuf[ibp];
}
static inline int fgetint(){
int n = 0, ch;
while( !isdigit(ch = fgetc(fin)) );
do
n = n * 10 + ch - '0';
while( isdigit(ch = fgetc(fin)) );
return n;
}
int main(){
fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");
int n, m, i, a, b;
n = fgetint();
for( i = 0 ; i < n ; i++ )
kids[i] = NIL;
m = fgetint();
for( i = 0 ; i < n - 1 ; i++ ){
a = fgetint() - 1;
adj[i] = i + 1;
next[i] = kids[a];
kids[a] = i;
}
// parcurgerea euler
sp = 0;
depth[0] = 0;
getEuler(0, 0);
rmqInit(sp);
for( ; m-- ; ){
a = fgetint() - 1;
b = fgetint() - 1;
fprintf(fout, "%d\n", 1 + rmqQuery(first[a], first[b]));// n-am chef si de parsare de out
}
fclose(fin);
fclose(fout);
return 0;
}