Cod sursa(job #739061)

Utilizator test0Victor test0 Data 21 aprilie 2012 23:30:31
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.08 kb
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#define MAX 100001
using namespace std;
vector<int>arb[MAX];
int v[MAX],niv[MAX],k,n,m,pos[MAX],c[MAX][20];

void euler(int x,int l){
    v[++k]=x;
    niv[k]=l;
    for(int i=0;i<arb[x].size();i++){
        euler(arb[x][i],l+1);
    v[++k]=x;
    niv[k]=l;}
}

void RMQ(){
    int i,j;
    for(i=1;i<=k;i++)c[i][1]=v[i];
    for(j=2;1<<(j-2)<=k;j++)
    for(i=1;i+(1<<(j-2))<=k;i++)
    c[i][j]=min(c[i][j-1],c[i+(1<<(j-2))][j-1]);
}

int main(){
    int x,y,z;
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
        scanf("%d %d",&n,&m);
        for(int i=2;i<=n;i++){
            scanf("%d",&x);
            arb[x].push_back(i); }
    euler(1,0);
    RMQ();
    for(int i=1;i<=k;i++)
    if(!pos[v[i]])pos[v[i]]=i;
    //for(int i=1;i<=n;i++)printf("%d ",pos[i]);

        for(int i=1;i<=m;i++){
            scanf("%d %d",&x,&y);
        x=pos[x]; y=pos[y]; if(x>y)swap(x,y);
        z=(long double)log10(y-x+1)/(long double)log10(2)+1;
        printf("%d\n",min(c[x][z],c[y-(1<<(z-1))+1][z]));
    }
}