Cod sursa(job #1559104)

Utilizator dutzulBodnariuc Dan Alexandru dutzul Data 30 decembrie 2015 03:00:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <bits/stdc++.h>
using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

#define LE 200666
#define pb push_back
#define lsb(X) (X&(X^(X-1)))

int fap[LE],lap[LE],my_stack[LE],lev[LE],k;
vector<int> H[LE];
bool viz[LE];
int stack_size,random_up[LE],fth[LE];
int nr_op;


void dfs(int nod)
{
    int N=H[nod].size(),i;
    viz[nod]=true;
    fap[nod]=++k;

    my_stack[++stack_size]=nod;
    int D=max(stack_size-lsb(stack_size),1);

    random_up[nod]=my_stack[D];

    for(i=0; i<N; ++i)
        if (viz[H[nod][i]]==false)
        {
            lev[H[nod][i]]=lev[nod]+1;
            dfs(H[nod][i]);
        }

    --stack_size;
    lap[nod]=k;
}

bool is_inside(int n1,int n2)
{
    return (fap[n2]>=fap[n1]&&fap[n2]<=lap[n1]);
}

int LCA(int n1,int n2)
{
    while (n1!=n2)
    {
        ++nr_op;

        if (is_inside(random_up[n1],n2)==false)
        {
            n1=random_up[n1];
            continue;
        }
        if (is_inside(random_up[n2],n1)==false)
        {
            n2=random_up[n2];
            continue;
        }

       if (n1!=n2)
        {
            if (lev[n1]>=lev[n2]) n1=fth[n1];
            else n2=fth[n2];
        }
    }

    return n1;
}

int main()
{
    int n,i,m;
    f>>n>>m;
   // cout<<n<<'\n';
    srand(666);

    for(i=2; i<=n; ++i)
    {
        f>>fth[i];
        H[fth[i]].pb(i);
        H[i].pb(fth[i]);
    }

    dfs(1);

    for(i=1; i<=m; ++i)
    {
        int xx,yy;
        f>>xx>>yy;
        nr_op=0;
        g<<LCA(xx,yy)<<'\n';

       // cout<<nr_op<<'\n';
    }



    return 0;
}