Cod sursa(job #1819330)

Utilizator alittlezzCazaciuc Valentin alittlezz Data 30 noiembrie 2016 15:14:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <cstdio>
#include <vector>

using namespace std;

vector <int> v[100005];
int position[200005];
int first[100005];
int depth[100005];
int rmq[18][200005];
int lg2[200005];

int mini(int i, int j){
    if(depth[i] < depth[j]){
        return i;
    }
    return j;
}

void dfs(int node, int cdepth, int& pos){
    depth[node] = cdepth;
    position[pos] = node;
    first[node] = pos;
    pos++;
    for(auto it : v[node]){
        dfs(it, cdepth + 1, pos);
        position[pos] = node;
        pos++;
    }
}

void init(int n){
    int i,j;
    lg2[2] = 1;
    for(i = 3;i <= n;i++){
        lg2[i] = lg2[i>>1] + 1;
    }
    for(i = 1;i <= n;i++){
        rmq[0][i] = position[i];
    }
    for(j = 1;j <= lg2[n];j++){
        int limit = n - ((1<<j)-1);
        for(i = 1;i <= limit;i++){
            rmq[j][i] = mini(rmq[j-1][i], rmq[j-1][i + (1<<(j-1))]);
        }
    }
}

int query(int lf, int rg){
    if(lf > rg){
        swap(lf, rg);
    }
    int pos = lg2[rg - lf + 1];
    return mini(rmq[pos][lf], rmq[pos][rg - (1<<pos) + 1]);
}

int main(){
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    int n,q,i,x,y,j;
    scanf("%d %d", &n, &q);
    for(i = 1;i < n;i++){
        scanf("%d", &x);
        v[x].push_back(i + 1);
    }
    int pos = 1;
    dfs(1, 0, pos);
    init(pos - 1);
    for(i = 1;i <= q;i++){
        scanf("%d %d", &x, &y);
        printf("%d\n", query(first[x], first[y]));
    }
    return 0;
}