Cod sursa(job #1546751)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 8 decembrie 2015 17:49:23
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include <cstdio>
#define MAXN 100000
#define LOGN 17
#define MAXE 8000000
int ind[MAXN+1],next[2*MAXN+1],v[2*MAXN+1],cod[MAXN],dist[MAXN+1],nr=1;
int ve[MAXE+1],de[MAXE+1],rmq[2*MAXN+1][LOGN],log[MAXE],ap[MAXN+1];
char vf[MAXN+1];
inline void add(int x,int y){
    next[nr]=ind[x];
    ind[x]=nr;
    v[nr]=y;
    nr++;
}
void euler(int nod){
    int poz;
    ve[nr]=nod;
    vf[nod]=1;
    nr++;
    poz=ind[nod];
    while(poz){
        if(vf[v[poz]]!=1){
           euler(v[poz]);
           ve[nr]=nod;
           nr++;
        }
        poz=next[poz];
    }
}
inline void BFS(int nod){
    int b,e,poz;
    cod[0]=nod;
    dist[1]=1;
    b=0;
    e=1;
    do{
        poz=ind[cod[b]];
        while(poz){
            if(dist[v[poz]]==0){
                dist[v[poz]]=dist[cod[b]]+1;
                cod[e]=v[poz];
                e++;
            }
            poz=next[poz];
        }
        b++;
    }while(b<e);
}
inline int getmin(int a,int b){
    if(a<b) return a;
    return b;
}
int main(){
    FILE*fi,*fout;
    int n,q,i,x,p2,j,y,pmax,pmin;
    fi=fopen("lca.in" ,"r");
    fout=fopen("lca.out" ,"w");
    fscanf(fi,"%d%d" ,&n,&q);
    for(i=2;i<=n;i++){
        fscanf(fi,"%d" ,&x);
        add(i,x);
        add(x,i);
    }
    BFS(1);
    nr=1;
    euler(1);
    for(i=1;i<nr;i++){
        de[i]=dist[ve[i]];
        if(ap[ve[i]]==0)
            ap[ve[i]]=i;
    }
    for(i=1;i<nr;i++)
        rmq[i][0]=i;
    for(i=1;(1<<i)<=nr;i++)
        for(j=1;j+(1<<i)<=nr;j++)
            if(de[rmq[j][i-1]]<de[rmq[j+(1<<(i-1))][i-1]])
                rmq[j][i]=rmq[j][i-1];
            else
                rmq[j][i]=rmq[j+(1<<(i-1))][i-1];
    p2=i=1;
    int con=0;
    while(i<=nr){
        if(p2*2<=i){
            p2*=2;
            con++;
        }
        log[i]=con;
        i++;
    }
    while(q){
        q--;
        fscanf(fi,"%d%d" ,&x,&y);
        if(x==y)
            fprintf(fout,"%d\n" ,x);
        else{
        if(ap[x]>ap[y]){
            pmax=ap[x];
            pmin=ap[y];
        }
        else{
            pmax=ap[y];
            pmin=ap[x];
        }
        if(de[rmq[pmin][log[pmax-pmin]]]>de[rmq[pmax-(1<<(log[pmax-pmin]))][log[pmax-pmin]]])
            fprintf(fout,"%d\n" ,ve[rmq[pmax-(1<<(log[pmax-pmin]))][log[pmax-pmin]]]);
        else
            fprintf(fout,"%d\n" ,ve[rmq[pmin][log[pmax-pmin]]]);
        }
    }
    fclose(fi);
    fclose(fout);
    return 0;
}