Cod sursa(job #2429745)

Utilizator stefanpiturStefan Alexandru Pitur stefanpitur Data 11 iunie 2019 00:25:30
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int NMAX = 100001;
vector <int> G[NMAX];
pair <int, int> euler[2 * NMAX];
int ap_pozitie[NMAX];
int poz;
int tabel[2 * NMAX][18];
int log[2 * NMAX];

void creare(int nod, int adancime){
    euler[++poz] = make_pair(nod,adancime);
    if(ap_pozitie[nod] == 0)
        ap_pozitie[nod] = poz;
    for(int p = 0; p < G[nod].size(); p++){
        creare(G[nod][p], adancime + 1);
        euler[++poz] = make_pair(nod, adancime);
    }
    return;
}

int min(int a, int b){
    return euler[a].second < euler[b].second ? a : b;
}

int query(int x, int y){
    if(x > y){
        int aux =  y;
        y = x;
        x = aux;
    }
    int elemente = y - x + 1;
    int slice = log[elemente];
    int ramase = elemente - (1<<slice);
    return min(tabel[x][slice],tabel[x + ramase][slice]);
}

int main()
{
    FILE *fin, *fout;
    int n,m,i,j,x,y,ans,lung;
    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);
    }
    creare(1, 0);
    lung = poz;
    log[1] = 0;
    for(i=2;i<=lung;i++)
        log[i] = log[i / 2] + 1;
    for(i=1;i<=poz;i++)
        tabel[i][0] = i;
    for(j=1;(1<<j)<lung;j++)
        for(i=1;(i + (1<<j) - 1) <= lung; i++)
            tabel[i][j] = min(tabel[i][j-1], tabel[i + (1<<(j - 1))][j-1]);
    for(i=1;i<=m;i++){
        fscanf(fin,"%d %d",&x,&y);
        ans = query(ap_pozitie[x],ap_pozitie[y]);
        fprintf(fout,"%d\n",euler[ans].first);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}