Cod sursa(job #1146752)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 19 martie 2014 11:31:12
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include<cstdio>
#include<vector>
using namespace std;
struct Vertex{
    int vertex,depth;
};
const int N=100000;
vector<int>sons[N];
Vertex r[18][N+1];
int e[2*N+1],depth[N+1],first[N+1],eDepth[2*N+1],log2[2*N+1];
int n,m,eL;
void citire(){
    int i,scan;
    scanf("%d%d",&n,&m);
    for(i=1;i<n;i++){
        scanf("%d",&scan);
        sons[scan].push_back(i+1);
    }
}
void init(){
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    citire();
}
void dFS(int x){
    int i;
    e[++eL]=x;
    eDepth[eL]=depth[x];
    first[x]=eL;
    for(i=0;i<sons[x].size();i++){
        depth[sons[x][i]]=depth[x]+1;
        dFS(sons[x][i]);
        e[++eL]=x;
        eDepth[eL]=depth[x];
    }
}
Vertex min2(Vertex x,Vertex y){
    if (x.depth>y.depth)
        x=y;
    return x;
}
void setR(){
    int i,j;
    for(i=2;i<=eL;i++)
        log2[i]=log2[i/2]+1;
    for(i=1;i<=eL;i++){
        r[0][i].depth=eDepth[i];
        r[0][i].vertex=e[i];
    }
    for(i=1;(1<<i)<=eL;i++)
        for(j=1;j<=eL-(1<<i)+1;j++)
            r[i][j]=min2(r[i-1][j],r[i-1][(j+(1<<(i-1)))]);
}
void change(int &x,int &y){
    int aux=x;
    x=y;
    y=aux;
}
int rMQ(int x,int y){
    x=first[x];
    y=first[y];
    if(x>y)
        change(x,y);
    return min2(r[log2[y-x+1]][x],r[log2[y-x+1]][y-(1<<(log2[y-x+1]))+1]).vertex;
}
int main(){
    int i,x,y;
    init();
    dFS(1);
    setR();
    for(i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        printf("%d\n",rMQ(x,y));
    }
    return 0;
}