Cod sursa(job #2055151)

Utilizator danstefanDamian Dan Stefan danstefan Data 2 noiembrie 2017 21:39:05
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.12 kb
#include <bits/stdc++.h>
using namespace std;
int n,i,q,x,niv[100010],dp[20][200010],y,lg[200010],first[100010],m,j,a,b,lu;
vector<int>g[100010];
void dsf(int node,int ni)
{
    first[node]=m;
    for(auto&it:g[node])
    {
        dp[++m][0]=it;
        niv[it]=niv[node]+1;
        dsf(it,ni+1);
        dp[++m][0]=node;
    }
}
int main()
{
    ifstream cin ("lca.in");
    ofstream cout ("lca.out");
    cin>>n>>q;
    for(i=2; i<=n; ++i)
    {
        cin>>x;
        g[x].push_back(i);
    }
    dp[++m][0]=1;
    niv[m]=0;
    dsf(1,0);
    for(j=1; (1<<j)<=m; ++j)
        for(i=1; i<=m-(1<<j)+1; ++i)
        {
            a=dp[i][j-1];
            b=dp[i+(1<<(j-1))][j-1];
            if(niv[a]<niv[b])dp[i][j]=a;
            else dp[i][j]=b;
        }
    for(i=1; i<=m; ++i)
        lg[i]=lg[i/2]+1;
    while(q--)
    {
        cin>>x>>y;
        x=first[x];
        y=first[y];
        if(x>y)swap(x,y);
        lu=y-x+1;
        a=dp[x][lg[lu-1]];
        b=dp[y-(1<<lg[lu-1])+1][lg[lu-1]];
        if(niv[a]<niv[b])cout<<a<<'\n';
        else cout<<b<<'\n';
    }
    return 0;
}