Cod sursa(job #2380540)

Utilizator dobrandreiAndrei Dobra dobrandrei Data 15 martie 2019 10:12:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <stdio.h>

using namespace std;
FILE *in,*out;

int n,m,k;
int lev[200002],poz[200002],rmq[45][200002],log2[200002],start[200002];
struct{
    int node, next;
}v[100002];

void read(){
    int x,kk=0;
    fscanf(in,"%d %d",&n,&m);
    for(int i=2;i<=n;i++){
        fscanf(in,"%d",&x);
        v[++kk].node=i;
        v[kk].next=start[x];
        start[x]=kk;
    }
}

void dfs(int node, int lv){
    rmq[0][++k]=node;
    if(!poz[node])
        poz[node]=k;
    for(int i=start[node];i;i=v[i].next){
        if(!lev[v[i].node]){
            lev[v[i].node]=lv+1;
            dfs(v[i].node,lv+1);
            rmq[0][++k]=node;
        }
    }
}

void log(){
    for(int i=2;i<=k;i++)
        log2[i]=log2[i/2]+1;
}

void build_rmq(){
    for(int i=1;i<=log2[k];i++){
        int pow=1<<(i-1);
        for(int j=1; j<=k-pow+1; j++){
            if(lev[rmq[i-1][j]]<lev[rmq[i-1][j+pow]])
                rmq[i][j]=rmq[i-1][j];
            else
                rmq[i][j]=rmq[i-1][j+pow];
        }
    }
}
void write(int a, int b)
{
    int z=log2[b-a+1];
    if(lev[rmq[z][a]]<lev[rmq[z][b-(1<<z)+1]])
        fprintf(out,"%d\n",rmq[z][a]);
    else
        fprintf(out,"%d\n",rmq[z][b-(1<<z)+1]);
}

void solve(){
    dfs(1,0);
    log();
    build_rmq();
    int a,b;
    while(m--){
        fscanf(in,"%d %d",&a,&b);
        a=poz[a];
        b=poz[b];
        if(a>b){
            int aux=a;
            a=b;
            b=aux;
        }
        write(a,b);
    }
}

int main(){
    in=fopen("lca.in","r");
    out=fopen("lca.out","w");
    read();
    solve();
    return 0;
}