Cod sursa(job #2164848)

Utilizator mateibanuBanu Matei Costin mateibanu Data 13 martie 2018 10:05:13
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.35 kb
#include <bits/stdc++.h>

using namespace std;

#define NMAX 100010LL
#define ll long long
ll t[NMAX],euler[2*NMAX],nr,n,m,nivel[2*NMAX],prima[NMAX],viz[NMAX],a[NMAX][20];

vector<ll> v[NMAX];

void df(ll nod, ll niv){
    euler[++nr]=nod;
    nivel[nr]=niv;
    if (!prima[nod]) prima[nod]=nr;
    ll l=v[nod].size();
    for (ll i=0;i<l;i++){
        if (!prima[v[nod][i]]){
            df(v[nod][i],niv+1);
            euler[++nr]=nod;
            nivel[nr]=niv;
        }
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    ll i,r,x,j,y;
    scanf("%lld%lld",&n,&m);
    t[1]=1;
    for (i=2;i<=n;i++){
        scanf("%lld",&t[i]);
        v[t[i]].push_back(i);
    }

    df(1,0);

    for (i=1;i<=nr;i++) a[i][0]=i;
    r=log2(nr);
    for (j=1;j<=r;j++)
        for (i=1;i<=nr-(1<<j)+1;i++){
            if (nivel[a[i][j-1]]>nivel[a[i+(1<<(j-1))][j-1]])
                a[i][j]=a[i+(1<<(j-1))][j-1];
            else a[i][j]=a[i][j-1];
        }

    for (i=1;i<=m;i++){
        scanf("%lld%lld",&x,&y);
        x=prima[x];
        y=prima[y];
        if (x>y) swap(x,y);
        r=log2(y-x+1);
        if (nivel[a[x][r]]>nivel[a[y-(1<<r)+1][r]])
                printf("%lld\n",euler[a[y-(1<<r)+1][r]]);
            else printf("%lld\n",euler[a[x][r]]);
    }
    return 0;
}