Cod sursa(job #1555564)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 23 decembrie 2015 09:35:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.62 kb
#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]=i;
    }
    for(i=1; (1<<i)<=u; i++){
        for(j=1; j<=u; j++){
            if(h[e[rmq[i-1][j]]]<h[e[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[e[rmq[lg[f[y]-f[x]+1]][f[y]]]]<h[e[rmq[lg[f[y]-f[x]+1]][f[x]+(1<<(lg[f[y]-f[x]+1]))-1]]]){
        return e[rmq[lg[f[y]-f[x]+1]][f[y]]];
    }else{
        return e[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;
}