Cod sursa(job #1140888)

Utilizator teoionescuIonescu Teodor teoionescu Data 12 martie 2014 12:43:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include<fstream>
#include<vector>
#define Emin(x,y) ( E[x] < E[y] ? x : y)
#define min(x,y) ( x < y ? x : y)
#define doila(x) (1<<x)
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int Nmax = 100005;
vector<int> G[Nmax];
int E[2*Nmax],K;
int first[Nmax];
int N,M;
void Dfs(int i){
    E[++K]=i;
    if(!first[i]) first[i]=K;
    for(vector<int>::iterator it=G[i].begin();it!=G[i].end();++it){
        Dfs(*it);
        E[++K]=i;
    }
}
int rmq[18][2*Nmax];
int lg[2*Nmax];
void procRMQ(){
    int i,j;
    for(i=2;i<=K;i++) lg[i]=lg[i/2]+1;
    for(j=1;j<=K;j++) rmq[0][j]=j;
    for(i=1;i<=lg[K];i++){
        for(j=1;j<=K-doila(i)+1;j++){
            rmq[i][j]=Emin(rmq[i-1][j],rmq[i-1][j+doila(i-1)]);
        }
    }
}
int RMQ(int x,int y){
    int dist=y-x+1;
    int block=lg[dist];
    int shift=dist-doila(block);
    return Emin(rmq[block][x],rmq[block][x+shift]);
}
int main(){
    in>>N>>M;
    for(int i=2;i<=N;i++){
        int t;
        in>>t;
        G[t].push_back(i);
    }
    Dfs(1);
    procRMQ();
    for(;M;--M){
        int x,y;
        in>>x>>y;
        x=first[x];
        y=first[y];
        if(y<x){
            int aux=x;
            x=y;
            y=aux;
        }
        out<<E[RMQ(x,y)]<<'\n';
    }
    return 0;
}