Cod sursa(job #2155259)

Utilizator andrei.gramescuAndrei Gramescu andrei.gramescu Data 7 martie 2018 18:56:25
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define NMAX 100005
#define LOGMAX 30

int n, m, LOGA[NMAX * 2 + 5], sparce[NMAX * 2 + 5][LOGMAX], poz[NMAX];
vector<int> a[NMAX], euler, h;

void buildEuler(int node, int dist){

    euler.push_back(node);
    h.push_back(dist);

    if(!poz[node] && node != 1)
        poz[node] = h.size() - 1;

    int i, child;
    for(i=0; i<(int) a[node].size(); i++){
        child = a[node][i];
        buildEuler(child, dist + 1);
        h.push_back(dist);
        euler.push_back(node);
    }
}

int main(){

    int x, y, i, j, index, l, k, low, high, rez, saiz;
    FILE *fin, *fout;
    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);
        a[x].push_back(i);
    }

    poz[1] = 0;
    buildEuler(1, 0);

    ///building sparce table
    saiz = (int) h.size();
    for(i=2; i<=saiz; i++)
        LOGA[i] = LOGA[i/2] + 1;

    for(i=0; i<saiz; i++)
        sparce[i][0] = i;

    for(j=1; (1 << j) <= saiz; j++){
        for(i=0; i + (1 << j) - 1 <= saiz; i++){
            if(h[ sparce[i][j-1] ] < h[ sparce[i + (1 << (j-1))][j-1] ])
                sparce[i][j] = sparce[i][j-1];
            else sparce[i][j] = sparce[i + (1 << (j-1))][j-1];
        }
    }

    ///lca
    for(i=1; i<=m; i++){
        fscanf(fin, "%d %d", &x, &y);
        low = min(poz[x], poz[y]);
        high = max(poz[x], poz[y]);

        l = high - low + 1;
        k = LOGA[l];
        if(h[ sparce[low][k] ] < h[ sparce[low + l - (1 <<  k)][k] ])
            rez = sparce[low][k];
        else rez = sparce[low + l - (1 <<  k)][k];

        fprintf(fout, "%d\n", euler[rez]);
    }

    fclose(fin);
    fclose(fout);

    return 0;
}