Cod sursa(job #2207661)

Utilizator NToniBoSSNicolae Tonitza NToniBoSS Data 26 mai 2018 12:14:44
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#include <vector>
#define LIM 1<<17
/// TONI BO$$ was here
/// #MLC

using namespace std;
char BUF[LIM];
int poz;

inline char getChar(){
    poz++;
    if(poz>=LIM){
    	fread(BUF,LIM,1,stdin);
    	poz=0;
    }
    return BUF[poz];
}

inline int getNr(){
    int r=0, semn=1;
    char ch=getChar();
    while(isdigit(ch)==0 && ch!='-') ch=getChar();
    if(ch=='-'){
        semn=-1;
        ch=getChar();
    }
    while(isdigit(ch)!=0){
        r=r*10+semn*(ch-'0');
        ch=getChar();
    }
    return r;
}

vector <int> L[100001];
int f[100001],euler[200001],rmq[200001][18],nr,ap[100001],lg2[100001];

void dfs(int i)
{
    f[i]=1;
    euler[++nr]=i;
    for(auto it : L[i])
        if(!f[it])
        {
            dfs(it);
            euler[++nr]=i;
        }
}

int main()
{
    int n,m,i,x,y,p2,ct,a,b;
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    n=getNr();
    m=getNr();
    for(i=2; i<=n; i++)
    {
        x=getNr();
        L[x].push_back(i);
        L[i].push_back(x);
    }
    dfs(1);
    for(i=1; i<=nr; i++)
        if(!ap[euler[i]])
            ap[euler[i]]=i;
    for(i=1; i<=nr; i++)
        rmq[i][0]=euler[i];
    for(p2=2,ct=1; p2<=LIM && p2<=nr; p2*=2,ct++)
        for(i=p2; i<=nr; i++)
            rmq[i][ct]=min(rmq[i][ct-1],rmq[i-(p2>>1)][ct-1]);
    for(i=2; i<=nr; i++)
        lg2[i]=lg2[i/2]+1;
    while(m--)
    {
        x=getNr();
        y=getNr();
        a=min(ap[x],ap[y]);
        b=max(ap[x],ap[y]);
        printf("%d\n",min(rmq[a+(1<<lg2[b-a+1])-1][lg2[b-a+1]],rmq[b][lg2[b-a+1]]));
    }

    return 0;
}