Cod sursa(job #1869271)

Utilizator mihai.alphamihai craciun mihai.alpha Data 5 februarie 2017 18:27:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <stdio.h>
#include <stdlib.h>
#include <vector>

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

int n, m;

#define LOGMAX 20
#define NMAX 100010 * 2

#define getmin(a, b) (a < b) ? a : b
#define getmax(a, b) (a > b) ? a : b
inline void swap(int &a, int &b)  {
    int aux = a;
    a = b;
    b = aux;
}

int preul[NMAX + 1], rmq[LOGMAX + 1][NMAX + 1], Lg[NMAX + 1];
std::vector <int> v[NMAX + 1];

int nr;

void dfs(int nod)  {
    rmq[0][++nr] = nod;
    if(!preul[nod])  {
        preul[nod] = nr;
    }
    for(int i = 0;i < v[nod].size();i++)  {
        dfs(v[nod][i]);
        rmq[0][++nr] = nod;
    }
}

int main()  {
    fscanf(fin, "%d%d", &n, &m);
    for(int i = 2;i <= n;i++)  {
        int elem;
        fscanf(fin, "%d", &elem);
        v[elem].push_back(i);
    }
    dfs(1);
    for(int i = 2;i <= nr;i++)  {
        Lg[i] = Lg[i >> 1] + 1;
    }
    for(int i = 1;(1 << i) <= nr;i++)
        for(int j = 1;(1 << i) + j <= nr + 1;j++)
            rmq[i][j] = getmin(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
    for(int i = 1;i <= m;i++)  {
        int x, y;
        fscanf(fin, "%d%d", &x, &y);
        if(preul[x] > preul[y])
            swap(x, y);
        int d = preul[y] - preul[x] + 1;
        d = Lg[d];
        int a = getmin(rmq[d][preul[x]], rmq[d][preul[y] - (1 << d) + 1]);
        fprintf(fout, "%d\n", a);
    }
    fclose(fin);
    fclose(fout);
}