Cod sursa(job #2551724)

Utilizator NashikAndrei Feodorov Nashik Data 20 februarie 2020 09:22:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
//#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
vector<int>g[100005];
int euclid[200005];
int rmq[200005][20];
int niv[200005],cnt=0;
int lg[2000005];
int put[30];
int fr[100005];
void dfs(int v,int n){
    euclid[++cnt]=v;
    niv[cnt]=n;
    for(auto u:g[v]){
        dfs(u,n+1);
        euclid[++cnt]=v;
        niv[cnt]=n;
    }
}
int fa(int st,int dr){
    if(st>dr){
        swap(st,dr);
    }
    int dist=dr-st+1;
    int e=lg[dist];
    if(niv[rmq[st][e]]<niv[rmq[dr-put[e]+1][e]]){
        return euclid[rmq[st][e]];
    }
    return euclid[rmq[dr-put[e]+1][e]];
}
int que(int a,int b){
    return fa(fr[a],fr[b]);
}
ifstream cin("lca.in");
ofstream cout("lca.out");
int main(){
    int n,q,a,b;
    cin>>n>>q;
    for(int i=2;i<=n;i++){
        cin>>a;
        g[a].push_back(i);
    }
    dfs(1,1);
    for(int i=cnt;i>=1;i--){
        fr[euclid[i]]=i;
    }
    put[0]=1;
    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 i=1;i<=2*n-1;i++){
        rmq[i][0]=i;
    }
    for(int j=1;j<=18;j++){
        for(int i=1;i<=cnt;i++){
            if(i+put[j]-1>cnt)
                break;
            if(niv[rmq[i][j-1]]<niv[rmq[i+put[j-1]][j-1]]){
                rmq[i][j]=rmq[i][j-1];
            }
            else{
                rmq[i][j]=rmq[i+put[j-1]][j-1];
            }
        }
    }
    for(int i=1;i<=q;i++){
        cin>>a>>b;
        cout<<que(a,b)<<"\n";
    }
}