Cod sursa(job #1968794)

Utilizator ana-maria.simiAna-Maria Simionescu ana-maria.simi Data 17 aprilie 2017 21:09:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <vector>
#include <fstream>
 using namespace std;
#define MAX_N 100005
#define MAX_L 20
#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)
int k,n,m,L[200010],H[200010],Lg[200010],First[200010],Rmq[20][400020],i,x,j,l,sh,diff,sol,a,b;
vector <int> G[MAX_N];
ifstream fin ("lca.in");
ofstream fout ("lca.out");

void dfs(int nod, int lev)
{
    H[++k]=nod;
    L[k]=lev;
    First[nod]=k;

    for(vector <int> :: iterator it=G[nod].begin(); it!=G[nod].end(); it++)
    {
        dfs(*it, lev+1);
        H[++k]=nod;
        L[k]=lev;
    }
}

void rmq()
{
    for(i=2; i<=k; i++)
        Lg[i]=Lg[i>>1]+1;
    for(i=1; i<=k; i++)
        Rmq[0][i]=i;

    for(i=1; (1<<i)<k; i++)
        for(j=1; j<=k-(1<<i); j++)
        {
            l=1<<(i-1);
            Rmq[i][j]=Rmq[i-1][j];
            if(L[Rmq[i-1][j+l]]<L[Rmq[i][j]])
                Rmq[i][j]=Rmq[i-1][j+l];
        }
}

int lca(int x, int y)
{
    a=First[x];
    b=First[y];
    if(a>b)
        swap(a,b);
    diff=b-a+1;
    l=Lg[diff];
    sol=Rmq[l][a];
    sh=diff-(1<<l);
    if(L[sol]>L[Rmq[l][a+sh]])
        sol=Rmq[l][a+sh];
    return H[sol];
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for(i=2; i<=n; i++)
    {
        scanf("%d", &x);
        G[x].push_back(i);
    }
    dfs(1, 0);
    rmq();

    while(m--)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        printf("%d\n", lca(x, y));
    }
}