Cod sursa(job #1850218)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 18 ianuarie 2017 12:47:20
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <fstream>
#include <cstdio>
#include <vector>
#include <cmath>
#define Nmax 100001
using namespace std;

ofstream g("lca.out");

int n,m,t[Nmax],st[Nmax];
vector<int> F[Nmax];

struct ceva{
    int niv, nod;
}rmq[20][Nmax*3];

vector<ceva> E;


void dfs(int nod,int niv)
{
    if (!st[nod])
        st[nod] = E.size();
    ceva crt;
    crt.niv = niv;
    crt.nod = nod;
    E.push_back(crt);
    for (int i=0;i<F[nod].size();i++)
    {
        dfs(F[nod][i],niv+1);
        E.push_back(crt);
    }
}
int _abs(int x)
{
    if (x<0)
        return -x;
    return x;
}

int main()
{
    freopen("lca.in","r",stdin);
    scanf("%ld%ld",&n,&m);
    for (int i=1;i<n;i++)
    {
        scanf("%ld",&t[i+1]);
        F[t[i+1]].push_back(i+1);
    }
    dfs(1,1);

    for (int i=1;i<E.size();i++)
        rmq[0][i] = E[i];

    for (int i=1;(1<<i)<E.size();i++)
        for (int j=0;j+(1<<i)-1<E.size();j++)
        {
            if (rmq[i-1][j].niv<rmq[i-1][j+(1<<(i-1))].niv)
                rmq[i][j] = rmq[i-1][j];
            else
                rmq[i][j] = rmq[i-1][j+(1<<i-1)];
        }

    for (int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%ld%ld",&x,&y);
        int dist = _abs(st[x]-st[y])+1;
        if (st[x]>st[y])
            swap(x,y);
        int niv = log2(dist);
        if (rmq[niv][st[x]].niv<rmq[niv][st[y]-(1<<niv)+1].niv)
            g<<rmq[niv][st[x]].nod<<'\n';
        else
            g<<rmq[niv][st[y]-(1<<niv)+1].nod<<'\n';
    }

    return 0;
}