Cod sursa(job #2080199)

Utilizator xkz01X.K.Z. xkz01 Data 2 decembrie 2017 16:01:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.34 kb
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
#define f first
#define s second
#define NMAX 100001
using namespace std;
vector<int> a[NMAX];
int i, nrElem, k, x, y, rmq[18][2*NMAX], lgParc, lvl[NMAX], firstAp[NMAX], nr;
int min_euler(int x, int y){
    if (lvl[x]<=lvl[y]) return x; else return y;
}
void parcurge_euler(int poz, int niv){
    vector<int>::iterator it;
    rmq[0][++lgParc]=poz; lvl[poz]=niv; firstAp[poz]=lgParc;
    for (it=a[poz].begin();it!=a[poz].end();++it) {
        parcurge_euler(*it, niv+1);
        rmq[0][++lgParc]=poz;
    }
}
void make_rmq(){
    int i, j;
    ///rmq[x][y]=minimul pe intervalul[x, x+2^y-1]
    for (i=1;(1<<i)<=lgParc;++i)
        for (j=1;j+(1<<(i-1))<=lgParc;++j) {
            rmq[i][j]=min_euler(rmq[i-1][j], rmq[i-1][j+(1<<(i-1))]);
        }
}
int main(){
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d", &nrElem, &k);
    for (i=2;i<=nrElem;++i) {
        scanf("%d", &x); a[x].push_back(i);
    }
    lgParc=0; parcurge_euler(1, 0);
    make_rmq();
    for (i=1;i<=k;i++) {
        scanf("%d%d", &x, &y);if (x==y) {printf("%d\n", x); continue;}
        x=firstAp[x]; y=firstAp[y]; if (x>y) swap(x,y);
        nr=log2(y-x);
        printf("%d\n", min_euler(rmq[nr][x], rmq[nr][y-(1<<nr)+1]));
    }
    return 0;
}