Cod sursa(job #1423256)

Utilizator atatomirTatomir Alex atatomir Data 21 aprilie 2015 17:11:06
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <iostream>
#include <cstdio>
#include <vector>

using namespace std;

#define maxN 100011
#define maxLog 22
#define myIteration(node) auto it=list[(node)].begin();it!=list[(node)].end();it++

long n,m,i,x,l,r;
vector<long> list[maxN];
long wh[maxN];
vector<long> def,defH;
vector<long> rmq[maxLog],rmqH[maxLog];


void dfs(long node,long lvl){
    def.push_back(lvl); defH.push_back(node);  wh[node] = def.size()-1;
    for( myIteration(node) ){
        dfs(*it,lvl+1);
        def.push_back(lvl); defH.push_back(node);
    }
}

void make_rmq(){
    long i,j,actLog;
    long how=def.size();

    for(actLog=0;1<<(actLog+1) <= how;actLog++);
    rmq[0] = def; rmqH[0] = defH;
    for(i=1;i<=actLog;i++) rmq[i]  = vector<long>(how+10,0);
    for(i=1;i<=actLog;i++) rmqH[i] = vector<long>(how+10,0);

    for(i=1;i<=actLog;i++){
        long h = 1<<(i-1);
        for(j=1;j+(h<<1) <= how+1 ;j++){
            if(rmq[i-1][j] < rmq[i-1][j+h])
                rmqH[i][j] = rmqH[i-1][j];
            else
                rmqH[i][j] = rmqH[i-1][j+h];
            rmq[i][j] = min(rmq[i-1][j],rmq[i-1][j+h]);
        }
    }
}

long getMax(long l,long r){
    long how = r-l+1,actLog;
    for(actLog=0;1<<(actLog+1) <= how;actLog++);

    if(rmq[actLog][l] < rmq[actLog][r-(1<<actLog)+1])
        return rmqH[actLog][l];
    else
        return rmqH[actLog][r-(1<<actLog)+1];
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    scanf("%ld %ld",&n,&m);
    for(i=2;i<=n;i++){
        scanf("%ld",&x);
        list[x].push_back(i);
    }

    dfs(1,1);
    make_rmq();

    for(;m--;){
        scanf("%ld %ld",&l,&r);
        printf("%ld\n",getMax(wh[l],wh[r]));
    }

    return 0;
}