Cod sursa(job #2664225)

Utilizator NashikAndrei Feodorov Nashik Data 28 octombrie 2020 10:36:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.78 kb
//#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
vector <int> v[100005];
int nv[100005],fr[100005],po[30],lg[9000000],rmq[25][4000005];
int euclid[4000005],cnt=0,t[100005];
bool f[100005];
void dfs(int nod,int niv){
    euclid[++cnt]=nod;
    nv[nod]=niv;
    f[nod]=1;
    fr[nod]=cnt;
    for(auto u:v[nod]){
        if(f[u]==0){
            f[u]=1;
            dfs(u,niv+1);
            euclid[++cnt]=nod;
        }
    }

}
int que(int st,int dr){
    int log=lg[dr-st+1];
    if(nv[euclid[rmq[log][st]]]<nv[euclid[rmq[log][dr-po[log]+1]]]){
        return euclid[rmq[log][st]];
    }
    return euclid[rmq[log][dr-po[log]+1]];
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=2;i<=n;i++){
        cin>>t[i];
        v[t[i]].push_back(i);
    }
    dfs(1,1);
    /*for(int i=1;i<=cnt;i++){
        cout<<euclid[i]<<" ";
    }
    cout<<"\n";
    for(int i=1;i<=cnt;i++){
        cout<<nv[euclid[i]]<<" ";
    }
    cout<<"\n";
    */
    for(int i=1;i<=cnt;i++){
        rmq[0][i]=i;
    }
    po[0]=1;
    for(int i=1;i<=23;i++){
        po[i]=po[i-1]*2;
        lg[po[i]]++;
    }
    for(int i=1;i<=4000005;i++){
        lg[i]+=lg[i-1];
    }
    for(int i=1;i<=23;i++){
        for(int j=1;j<=cnt;j++){
            if(nv[euclid[rmq[i-1][j]]]<nv[euclid[rmq[i-1][min(j+po[i-1],cnt)]]]){
               rmq[i][j]=rmq[i-1][j];
            }
            else
                rmq[i][j]=rmq[i-1][min(j+po[i-1],cnt)];
        }
    }
    int a,b;
    for(int i=1;i<=m;i++){
        cin>>a>>b;
        a=fr[a];
        b=fr[b];
        //cout<<a<<" "<<b<<"\n";
        if(a>b)
            swap(a,b);
        cout<<que(a,b)<<"\n";
    }
    return 0;
}