Cod sursa(job #1598063)

Utilizator BlueStrutAndrei Prahoveanu BlueStrut Data 12 februarie 2016 16:35:44
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include<cstdio>
#include<vector>
#include<cmath>
#define f first
#define s second
using namespace std;
vector<int> grf[100002];
pair<int,int> a[17][50001];
int i, n, j, x, y, k, lg, nr, unde_apare[100002];
inline int min(int a, int b){if (a<=b) return a; else return b;}
int doi_la(int x){return (1<<x);}
void dfs(int poz, int h){
    vector<int>::iterator it;
    //a[][]=pair(cine e LCA, adancime LCA)
    a[0][++lg]=make_pair(poz, h);
    if (unde_apare[poz]==0) unde_apare[poz]=lg;
    for (it=grf[poz].begin();it!=grf[poz].end();it++) {
        x=*it;
        dfs(x, h+1);
        a[0][++lg]=make_pair(poz, h);
    }
}
void create_rmq(){
    //a[][]=pair(cine e LCA, adancime LCA)
    a[0][0].f=lg;
    for (i=1;doi_la(i)<=lg;i++)
        for (j=1;j+doi_la(i-1)<=a[i-1][0].f;j++) {
            a[i][0].f++;
            if (a[i-1][j].s<=a[i-1][j+doi_la(i-1)].s)
                a[i][j]=a[i-1][j];
                else a[i][j]=a[i-1][j+doi_la(i-1)];
        }
}
int main(){
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d", &n, &k); lg=0;
    for (i=2;i<=n;i++) {scanf("%d", &x); grf[x].push_back(i);}
    dfs(1, 0);
    create_rmq();
    for (i=1;i<=k;i++) {
        scanf("%d%d", &x, &y);
        x=unde_apare[x]; y=unde_apare[y]; if (x>=y) swap(x,y);
        nr=log2(y-x+1);
        //a[][]=pair(cine e LCA, adancime LCA)
        if (a[nr][x].s<=a[nr][y-doi_la(nr)+1].s) printf("%d\n", a[nr][x].f);
            else printf("%d\n", a[nr][y-doi_la(nr)+1].f);
    }
    return 0;
}