Pagini recente » Cod sursa (job #1813827) | Cod sursa (job #1075377) | Cod sursa (job #1606283) | Cod sursa (job #214358) | Cod sursa (job #1555565)
#include <cstdio>
#include <cctype>
#define BUF_SIZE 4096
#define MAXN 100000
#define MAXU (2*MAXN-1)
#define LOGU 17
int m, u;
int lista[MAXN+1], next[MAXN], val[MAXN], e[MAXU+1], h[MAXN+1], f[MAXN+1], lg[MAXU+1], rmq[LOGU+1][MAXU+1];
int poz=BUF_SIZE, pos=0;
char buf[BUF_SIZE], buf2[BUF_SIZE], c[10];
FILE *fin, *fout;
inline char nextch(){
if(poz==BUF_SIZE){
fread(buf, BUF_SIZE, 1, fin);
poz=0;
}
return buf[poz++];
}
inline int read(){
int x=0;
char ch=nextch();
while(!isdigit(ch)){
ch=nextch();
}
while(isdigit(ch)){
x=10*x+ch-'0';
ch=nextch();
}
return x;
}
inline void putch(char ch){
buf2[pos++]=ch;
if(pos==BUF_SIZE){
fwrite(buf2, BUF_SIZE, 1, fout);
pos=0;
}
}
inline void baga(int x){
int k=0;
do{
c[k++]=x%10+'0';
x/=10;
}while(x>0);
while(k){
k--;
putch(c[k]);
}
}
inline void adauga(int x, int y){
m++;
val[m]=y;
next[m]=lista[x];
lista[x]=m;
}
void dfs(int x){
int p=lista[x];
u++;
e[u]=x;
f[x]=u;
while(p){
if(h[val[p]]==0){
h[val[p]]=h[x]+1;
dfs(val[p]);
}
u++;
e[u]=x;
p=next[p];
}
}
inline void makeLog(){
int i;
for(i=2; i<=u; i++){
lg[i]=lg[i>>1]+1;
}
}
inline void makeRmq(){
int i, j;
for(i=1; i<=u; i++){
rmq[0][i]=e[i];
}
for(i=1; (1<<i)<=u; i++){
for(j=1; j<=u; j++){
if(h[rmq[i-1][j]]<h[rmq[i-1][j-(1<<(i-1))]]){
rmq[i][j]=rmq[i-1][j];
}else{
rmq[i][j]=rmq[i-1][j-(1<<(i-1))];
}
}
}
}
inline void precalc(){
h[1]=1;
dfs(1);
makeLog();
makeRmq();
}
inline int lca(int x, int y){
if(f[x]>f[y]){
int aux=x;
x=y;
y=aux;
}
if(h[rmq[lg[f[y]-f[x]+1]][f[y]]]<h[rmq[lg[f[y]-f[x]+1]][f[x]+(1<<(lg[f[y]-f[x]+1]))-1]]){
return rmq[lg[f[y]-f[x]+1]][f[y]];
}else{
return rmq[lg[f[y]-f[x]+1]][f[x]+(1<<(lg[f[y]-f[x]+1]))-1];
}
}
int main(){
int q, i, x, y, n;
fin=fopen("lca.in", "r");
fout=fopen("lca.out", "w");
n=read();
q=read();
for(i=2; i<=n; i++){
adauga(read(), i);
}
precalc();
for(i=1; i<=q; i++){
x=read();
y=read();
baga(lca(x, y));
putch('\n');
}
if(pos>0){
fwrite(buf2, pos, 1, fout);
}
fclose(fin);
fclose(fout);
return 0;
}