Cod sursa(job #1149437)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 21 martie 2014 20:48:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include<cstdio>
#include<vector>
using namespace std;
struct Vertex{
    int vertex,depth;
};
const int MAX_N=700000,MAX_LOG_N=40;
Vertex r[MAX_LOG_N+1][2*MAX_N+1];
int first[2*MAX_N+1],log2[2*MAX_N+1];
int n,m,eL,actualDepth;
vector <int> sons[MAX_N];
void read(){
    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);
    read();
}
void dfs(int father){
    int i;
    r[0][++eL].vertex=father;
    r[0][eL].depth=actualDepth;
    first[father]=eL;
    for(i=0;i<sons[father].size();i++){
        actualDepth++;
        dfs(sons[father][i]);
        actualDepth--;
        r[0][++eL].vertex=father;
        r[0][eL].depth=actualDepth;
    }
}
Vertex min2Vertex(Vertex v1,Vertex v2){
    if(v1.depth<v2.depth)
        return v1;
    return v2;
}
void setR(){
    int i,j;
    for(i=2;i<=eL;i++)
        log2[i]=log2[i/2]+1;
    for(i=1;(1<<i)<=eL;i++)
        for(j=1;j<=eL-(1<<i)+1;j++)
            r[i][j]=min2Vertex(r[i-1][j],r[i-1][(j+(1<<(i-1)))]);
}
int lca(int a, int b){
    a=first[a];
    b=first[b];
    if(a>b)
        swap(a,b);
    return min2Vertex(r[log2[b-a+1]][a],r[log2[b-a+1]][b-(1<<log2[b-a+1])+1]).vertex;
}
int main(){
    init();
    dfs(1);
    setR();
    int a,b;
    while(m>0)
    {
        m--;
        scanf("%d%d",&a,&b);
        printf("%d\n",lca(a,b));
    }
    return 0;
}