Cod sursa(job #1059094)

Utilizator dumitrualexAlex Dumitru dumitrualex Data 16 decembrie 2013 09:10:39
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <cstdio>
#include <vector>
#define nmax 100000+5
#define range(i, a, b) int i = (a); i <= (b); i++
#define every(it, C) vector<int>::iterator it = C.begin(); it != C.end(); it++
using namespace std;

vector<int> graf[nmax];
vector<int> euler;
int n;
int R[20][nmax];
int pozitieEuler[nmax];
int inaltime[nmax];

void parcurgereEuler(int nod, int h)
{
    euler.push_back(nod);
    pozitieEuler[nod] = euler.size();
    inaltime[nod] = h;

    if (!graf[nod].empty())
        for (every(fiu, graf[nod]))
        {
            parcurgereEuler(*fiu, h+1);
            euler.push_back(nod);
        }
}

void formareMatriceRMQ()
{
    int i, j;
    int l = euler.size();
    int x, y;

    for (j = 0; j < l; j++)
        R[0][j+1] = euler[j];
    for (i = 1; (1 << i) <= l; i++)
        for (j = 1; j + (1 << i) -1 <= l; j++)
        {
            x = R[i-1][j];
            y = R[i-1][j+(1<<(i-1))];

            if (inaltime[x] < inaltime[y])
                R[i][j] = x;
            else
                R[i][j] = y;
        }
}

int interogareRMQ(int x, int y)
{
    int a, b;
    int log = 0;
    while (1 << (log+1) <= y-x)
        log++;
    a = R[log][x];
    b = R[log][y-(1<<log)+1];

    if (inaltime[a] < inaltime[b])
        return a;
    else
        return b;
}

void debugRMQ()
{
    int i, j;
    int l = euler.size();
    for (i = 0; (1 << i) <= l; i++)
    {
        for (j = 0; j + (1 << i) -1 < l; j++)
            printf("%d\t", R[i][j]);
        printf("\n");
    }
    for (i = 1; i <= n; i++)
        printf("inaltime[%d] = %d\n", i, inaltime[i]);
}
int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    int m, x, y;
    scanf("%d%d", &n, &m);

    for (range(i, 2, n))
    {
        scanf("%d", &x);
        graf[x].push_back(i);
    }

    parcurgereEuler(1, 1);
    formareMatriceRMQ();

    //debugRMQ();
    for (range(i, 1, m))
    {
        scanf("%d%d", &x, &y);
        printf("%d\n", interogareRMQ(pozitieEuler[x], pozitieEuler[y] ));
    }
    return 0;
}