Cod sursa(job #1886696)

Utilizator alexionpopescuPopescu Ion Alexandru alexionpopescu Data 21 februarie 2017 08:34:22
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.26 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int> a[100001];
int e[400001],l[400001],lg[400001],f[400001],n,m,q;
int rmq[21][400001];
void cit(){
    int w;
    fin>>n>>m;
    for(int i=2;i<=n;i++){
        fin>>w;
        a[w].push_back(i);
    }
}
void dfs(int k,int nr){
    e[++q]=k;
    l[q]=nr;
    f[k]=q;
    for(int i=0;i<a[k].size();i++){
        dfs(a[k][i],nr+1);
        e[++q]=k;
        l[q]=nr;
    }
}
void RMQ(){
    int i,j;
    for(i=2;i<=q;i++)
        lg[i]=lg[i/2]+1;
    for(i=1;i<=q;i++)
        rmq[0][i]=i;
    for(i=1;(1<<i)<=q;i++)
        for(j=1;j<=q-(1<<i);j++){
            int w;
            w=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];
            if(l[rmq[i][j]]>l[rmq[i-1][j+w]])
                rmq[i][j]=rmq[i-1][j+w];
        }
}
int lca(int x,int y){
    x=f[x];
    y=f[y];
    if(x>y)
        swap(x,y);
    int w=lg[y-x+1],sol=rmq[w][x];
    if(l[sol]>l[rmq[w][y-(1<<w)+1]])
        sol=rmq[w][y-(1<<w)+1];
    return e[sol];
}
int main(){
    cit();
    dfs(1,0);
    RMQ();
    int q,w;
    for(int i=1;i<=m;i++){
        fin>>q>>w;
        fout<<lca(q,w)<<'\n';
    }
    fin.close();
    fout.close();
    return 0;
}