Cod sursa(job #1519516)

Utilizator akaprosAna Kapros akapros Data 7 noiembrie 2015 14:23:35
Problema Range minimum query Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxN 100002
#define maxL 20
using namespace std;
int n, m, nr, ne;
int e[maxN * 2], lev[maxN * 2], urm[2 * maxN], vf[maxN * 2], lst[maxN], t[maxN], pos[maxN], d[maxL][maxN * 2], Log[maxN * 2];
void add(int x, int y)
{
    ++ nr;
    vf[nr] = y;
    urm[nr] = lst[x];
    lst[x] = nr;
}
void read()
{
    int i, x;
    freopen("lca.in", "r", stdin);
    scanf("%d %d", &n, &m);
    for (i = 2; i <= n; ++ i)
    {
        scanf("%d", &x);
        add(x, i);
        t[i] = x;
    }
}
void euler(int x)
{
    e[++ ne] = x;
    if (pos[x] == 0)
        pos[x] = ne;
    lev[x] = lev[t[x]] + 1;
    int p = lst[x], y;
    while (p != 0)
    {
        y = vf[p];
        euler(y);
        e[++ ne] = x;
        p = urm[p];
    }
}
void solve()
{
    int i, j;
    for (i = 1; i <= ne; ++ i)
        d[0][i] = e[i];
    for (i = 2; i <= ne; ++ i)
        Log[i] = Log[i / 2] + 1;
    for (i = 1; i <= Log[ne]; ++ i)
        for (j = 1; j <= ne; ++ j)
        {
            d[i][j] = d[i - 1][j - (1 << (i - 1))];
            if (lev[d[i][j]] > lev[d[i - 1][j]])
                d[i][j] = d[i - 1][j];
        }
}
void write()
{
    int z, t, x, y, k;
    freopen("lca.out", "w", stdout);
    while (m --)
    {
        scanf("%d %d", &x, &y);
        z = pos[x];
        t = pos[y];
        if (z > t)
            swap(z, t);
        k = Log[t - z];
        if (lev[d[k][t]] < lev[d[k][z + (1 << k)]-1])
            printf("%d\n", d[k][t]);
        else
            printf("%d\n", d[k][z + (1 << k)-1]);
    }
}
int main()
{
    read();
    euler(1);
    solve();
    write();
    return 0;
}