Cod sursa(job #1110885)

Utilizator beldeabogdanBogdan Beldea beldeabogdan Data 18 februarie 2014 14:24:23
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.34 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#define nmax 200015
using namespace std;
 
vector <int> v[nmax];
int euler[nmax],ep;
int lev[nmax];
int pos[nmax];
int index[22][nmax];
int n,m;
 
void dfs(int n,int k) {
    euler[++ep] = n;
    lev[ep] = k;
    pos[n] = ep;
    while (!v[n].empty()) {
        dfs(v[n].back(),k+1);
        v[n].pop_back();
        euler[++ep] = n;
        lev[ep] = k;
    }
}
 
int log(int a) {
    int x=0;
    while ((1<<x) < a) x++;
    return x-1;
}
 
int main() {
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d %d",&n,&m);
    for (int i=1;i<n;i++) {
        int t;
        scanf("%d",&t);
        v[t].push_back(i+1);
    }
    dfs(1,1);
    for (int i=1;i<=ep;i++) index[0][i] = i;
    int tz = log(ep);
    for (int i=1;i<=tz;i++) {
        for (int j=1;j<=ep-(1<<i)+1;j++) {
            index[i][j] = (lev[index[i-1][j]]<lev[index[i-1][j+(1<<(i-1))]])?(index[i-1][j]):(index[i-1][j+(1<<(i-1))]);
        }
    }
    for (int i=1;i<=m;i++) {
        int a,b;
        scanf("%d %d",&a,&b);
        a = pos[a],b = pos[b];
        if (a > b) swap(a,b);
        int k = log(b-a+1);
        int r = (lev[index[k][a]] < lev[index[k][b-(1<<k)+1]])?(euler[index[k][a]]):(euler[index[k][b-(1<<k)+1]]);
        printf("%d\n",r);
    }
}