Cod sursa(job #1991346)

Utilizator al.mocanuAlexandru Mocanu al.mocanu Data 16 iunie 2017 13:17:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <stdio.h>
#include <vector>
#define MAX 100005
using namespace std;
 
int n, m, i, j, x, y, nr;
vector<int> l[MAX];
int rmq[20][2 * MAX], lvl[2 * MAX];
int euler[2 * MAX], log[2 * MAX], indici[MAX];
 
void constreuler(int x, int nivel);
void constrRMQ();
int LCA();
 
int main(){
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for(i = 2; i <= n; i++){
        scanf("%d", &x);
        l[x].push_back(i);
    }
 
    constreuler(1, 0);
    constrRMQ();
    LCA();
    return 0;
}
 
void constreuler(int x, int nivel){
    euler[++nr] = x;
    indici[x] = nr;
    lvl[nr] = nivel;
    int i;
    for(i = 0; i < l[x].size(); i++){
        constreuler(l[x][i], nivel + 1);
        euler[++nr] = x;
        lvl[nr] = nivel;
     }
}
 
void constrRMQ(){
    int i, j;
    for(i = 2; i <= nr; i++)
        log[i] = log[i / 2] + 1;
    for(i = 1; i <= nr; i++)
        rmq[0][i] = i;
    for(i = 1; i <= log[nr]; i++)
        for(j = 1; j <= nr - (1<<i) + 1; j++)
            if(lvl[rmq[i - 1][j]] < lvl[rmq[i - 1][j + (1<<(i-1))]])
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + (1<<(i-1))];
}
 
int LCA(){
    int u, v, d;
    for(i = 0; i < m; i++){
        scanf("%d%d", &u, &v);
        u = indici[u];
        v = indici[v];
 
        if(u > v)
            swap(u, v);
 
        d = log[v - u + 1];
        if(lvl[rmq[d][u]] < lvl[rmq[d][v - (1<<d) + 1]])
            printf("%d\n", euler[rmq[d][u]]);
        else
            printf("%d\n", euler[rmq[d][v - (1<<d) + 1]]);
    }
}