Mai intai trebuie sa te autentifici.
Cod sursa(job #1542792)
Utilizator | Data | 5 decembrie 2015 17:37:20 | |
---|---|---|---|
Problema | Lowest Common Ancestor | Scor | 100 |
Compilator | c | Status | done |
Runda | Arhiva educationala | Marime | 1.72 kb |
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXN 100000
#define LIM 8388608
FILE *fin;
char s[LIM];
int p=LIM-1;
void avans(){
if(++p==LIM){
fread(s, LIM, 1, fin);
p=0;
}
}
int getnr(){
int nr=0;
while(isdigit(s[p])==0)
avans();
while(isdigit(s[p])){
nr=nr*10+s[p]-'0';
avans();
}
return nr;
}
int vf[2*MAXN+1], lst[MAXN+1], next[2*MAXN+1], m;
int nod[2*MAXN+1], nivel[2*MAXN+1], prim[MAXN+1], k;
void euler(int x, int niv){
int p=lst[x];
nod[++k]=x; prim[x]=k; nivel[k]=niv;
while(p){
if(prim[vf[p]]==0){
euler(vf[p], niv+1);
nod[++k]=x; nivel[k]=niv;
}
p=next[p];
}
}
void add(int x, int y){
vf[++m]=y;
next[m]=lst[x];
lst[x]=m;
}
int rmq[2*MAXN+1][20], lg[2*MAXN+1];
int main()
{
FILE *fout;
int N, M, i, u, v, j, l;
fin=fopen("lca.in", "r");
N=getnr(); M=getnr();
for(i=2; i<=N; i++){
u=getnr();
add(i, u); add(u, i);
}
euler(1, 0);
for(i=2; i<=k; i++)
lg[i]=lg[i>>1]+1;
for(i=1; i<=k; i++)
rmq[i][0]=i;
for(i=1; (1<<i)<=k; i++){
l=1<<(i-1);
for(j=1; j<k-(1<<i); j++)
if(nivel[rmq[j][i-1]]<nivel[rmq[j+l][i-1]])
rmq[j][i]=rmq[j][i-1];
else
rmq[j][i]=rmq[j+l][i-1];
}
fout=fopen("lca.out", "w");
for(i=0; i<M; i++){
u=prim[getnr()]; v=prim[getnr()];
if(u>v){
l=u; u=v; v=l;
}
l=lg[v-u+1];
if(nivel[rmq[u][l]]<nivel[rmq[v-(1<<l)+1][l]])
fprintf(fout, "%d\n", nod[rmq[u][l]]);
else
fprintf(fout, "%d\n", nod[rmq[v-(1<<l)+1][l]]);
}
fclose(fin);
fclose(fout);
return 0;
}