Cod sursa(job #1869162)

Utilizator mihai.alphamihai craciun mihai.alpha Data 5 februarie 2017 17:15:37
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.35 kb
#include <stdio.h>
#include <stdlib.h>
#include <vector>

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

#define NMAX 100001
#define LOGMAX 18

#define getmin(a, b) (a < b) ? a : b
#define getmax(a, b) (b > a) ? b : a

int n, m, nr;
int rmq[LOGMAX + 1][NMAX + 1], lg[NMAX + 1], p[NMAX + 1];
std::vector <int> v[NMAX + 1];

inline void sw(int &a, int &b)  {
    int aux = a;
    a = b;
    b = aux;
}

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

int main(void)  {
    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 <= (getmax(n, nr));i++)
        lg[i] = lg[i >> 1] + 1;
    for(int j = 1;(1 << j) <= nr;j++)
        for(int i = 1;i + (1 << j) <= nr + 1;i++)
            rmq[j][i] = getmin(rmq[j - 1][i], rmq[j - 1][i + (1 << (j - 1))]);
    for(int i = 1;i <= m;i++)  {
        int a, b;
        fscanf(fin, "%d%d", &a, &b);
        if(p[a] > p[b])
            sw(a, b);
        int d = lg[p[b] - p[a]];
        fprintf(fout, "%d\n", getmin(rmq[d][p[a]], rmq[d][p[b] - (1 << d) + 1]));
    }
    fclose(fin);
    fclose(fout);
    return 0;
}