Cod sursa(job #2574784)

Utilizator NashikAndrei Feodorov Nashik Data 6 martie 2020 09:53:43
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.39 kb
//#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int euclid[200005],nv[200005],lg[2000000],put[25],cnt=0,fr[100005],rmq[25][100005];
vector<int> v[100005];
void dfs(int nod,int niv){
    euclid[++cnt]=nod;
    nv[cnt]=niv;
    for(auto u:v[nod]){
        dfs(u,niv+1);
        euclid[++cnt]=nod;
        nv[cnt]=niv;
    }
}
int ma(int a,int b){
    if(nv[a]<nv[b])
        return a;
    return b;
}
int find_lca(int a,int b){
    a=fr[a];
    b=fr[b];
    if(a>b)
        swap(a,b);
    int dist=b-a+1;
    int e=lg[dist];
    return euclid[ma(rmq[e][a],rmq[e][b-put[e]+1])];
}
int main()
{
    int n,m,a,b;
    cin>>n>>m;
    for(int i=2;i<=n;i++){
        cin>>a;
        v[a].push_back(i);
    }
    dfs(1,1);
    for(int i=1;i<=cnt;i++){
        rmq[0][i]=i;
    }
    put[0]++;
    for(int i=1;i<=20;i++){
        put[i]=put[i-1]*2;
        lg[put[i]]++;
    }
    for(int i=1;i<=1000000;i++)
        lg[i]+=lg[i-1];
    for(int j=1;j<=20;j++){
        for(int i=1;i<=cnt;i++){
            if(i+put[j]-1>cnt)
                break;
            rmq[j][i]=ma(rmq[j-1][i],rmq[j-1][i+put[j-1]]);
        }
    }
    for(int i=cnt;i>=1;i--){
        fr[euclid[i]]=i;
    }
    for(int i=1;i<=m;i++){
        cin>>a>>b;
        cout<<find_lca(a,b)<<"\n";
    }
    return 0;
}