Cod sursa(job #1469417)

Utilizator armandpredaPreda Armand armandpreda Data 8 august 2015 12:05:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.34 kb
#include <cstdio>
#include <vector>
#define minim(a, b) (niv[a]<niv[b])?(a):(b)

using namespace std;

const int LIM=100001;
int n, q, eul[18][2*LIM], neul, niv[LIM], poz[LIM], lg[2*LIM];
vector <int> gr[LIM];
void dfs(int nod, int lvl)
{
    eul[0][++neul]=nod;
    niv[nod]=lvl;
    if(poz[nod]==0) poz[nod]=neul;
    for(int i=0; i<gr[nod].size(); ++i)
    {
        dfs(gr[nod][i], lvl+1);
        eul[0][++neul]=nod;
    }
}
void build_eul()
{
    for(int i=2; i<=neul; ++i)
        lg[i]=1+lg[i/2];
    for(int i=1; i<=lg[neul]; ++i)
        for(int j=1; j<=neul+1-(1<<i); ++j)
            eul[i][j]=minim(eul[i-1][j], eul[i-1][ j+(1<<(i-1)) ]);
}
int ans(int x, int y)
{
    if(poz[x]>poz[y])
    {
        int cop;
        cop=x, x=y, y=cop;
    }
    x=poz[x], y=poz[y];
    int lin=lg[y-x+1];
    if(niv[ eul[lin][x] ]<niv[ eul[lin][ y+1-(1<<lin) ] ])
        return eul[lin][x];
    else
        return eul[lin][ y+1-(1<<lin) ];
}
int main()
{
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	scanf("%d%d", &n, &q);
	for(int i=2; i<=n; ++i)
    {
        int x;
        scanf("%d", &x);
        gr[x].push_back(i);
    }
    dfs(1, 0);
    build_eul();
    while(q--)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        printf("%d\n", ans(x, y));
    }
	return 0;
}