Cod sursa(job #2294992)

Utilizator DragosArseneDragos Arsene DragosArsene Data 2 decembrie 2018 23:40:38
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.16 kb
#include <iostream>
#include <stdio.h>
#include <vector>

using namespace std;
int euler[300001], nivel[300001], poz[100001], log[100001], niv[100001];
int lookup_table[20][300001];
vector <int> g[100001];
int i, it=0, j;
int nod_curent;

void dfs(int nod, int i){
int nod_vecin;
euler[++it]=nod;
for(i=0;i<g[nod].size();i++){
    nod_vecin=g[nod][i];
    j=i;
	if(nivel[g[nod][i]]==-2){
    nivel[g[nod][i]]=nivel[nod]+1;
    dfs(g[nod][j], i);
    euler[++it]=nod;
	}


}

}

int main() {
    FILE *fin,*fout;

    int n, m, x, j, x1, y1, ans, logn, d, x2, y2, p2;



fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");



fscanf(fin,"%d%d", &n, &m);

for(i=2;i<=n;i++){

    fscanf(fin,"%d", &x);
    g[x].push_back(i);
    g[i].push_back(x);
}

for(i=1;i<=n;i++){
    nivel[i]=-2;
}

nivel[1]=0;
dfs(1, 0);

for(i=1;i<=it;i++){
    lookup_table[0][i]=i;
}

for(i=1;i<=it;i++){
    niv[i]=nivel[euler[i]];

}
for(i=1;i<=it;i++){
    if(poz[euler[i]]==0)
        poz[euler[i]]=i;
}


for(i=1;i<=it;i++){
    if(niv[i]<=niv[i+1])
    lookup_table[1][i]=i;
    else
    lookup_table[1][i]=i+1;
}

i=1;
logn=0;
while(i<it){
    if(i*2<=it){
    i*=2;
    logn++;
    }
    else
    i*=2;
}
p2=1;
log[1]=0;
for(i=2;i<=it+1;i++){
    if(i==2*p2){
    p2*=2;
    log[i]=log[i-1]+1;
    }
    else
    log[i]=log[i-1];
}
for(i=2;i<=logn;i++){
    for(j=1;j+(1<<i)-1<=it;j++){
        if(niv[lookup_table[i-1][j]]<=niv[lookup_table[i-1][j+(1<<i-1)]])
        lookup_table[i][j]=lookup_table[i-1][j];
        else
        lookup_table[i][j]=lookup_table[i-1][j+(1<<i-1)];

    }


}



for(j=1;j<=m;j++){
    fscanf(fin,"%d%d", &x1, &y1);
    if(poz[x1]<poz[y1]){
    x2=poz[x1];
    y2=poz[y1];
    }
    else{
    x2=poz[y1];
    y2=poz[x1];
    }
    d=y2-x2+1;
    if(niv[lookup_table[log[d-1]][x2]]<=niv[lookup_table[log[d-1]][y2-(1<<log[d-1])+1]])
    fprintf(fout,"%d\n", euler[lookup_table[log[d-1]][x2]]);
    else
    fprintf(fout,"%d\n", euler[lookup_table[log[d-1]][y2-(1<<log[d-1])+1]]);

}











fclose(fin);

fclose(fout);



    return 0;

}