Cod sursa(job #1525148)

Utilizator mariakKapros Maria mariak Data 14 noiembrie 2015 19:37:40
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <algorithm>
#include <cstdio>
#define log 20
#define Nmax 100002

using namespace std;
int n, m, E[Nmax * 2], poz[Nmax], lev[Nmax], t[Nmax], vf[Nmax * 2], lst[Nmax * 2], Prev[Nmax * 2];
int r[Nmax * 2][log], nr, x, Log[Nmax], a, b, L, Sol;
void Swap(int &x, int &y)
{
    int aux;
    aux = x;
    x = y;
    y = aux;
}
void add(int x, int y)
{
    ++ nr;
    vf[nr] = y;
    Prev[nr] = lst[x];
    lst[x] = nr;
}
void read()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    scanf("%d %d", &n, &m);
    for(int i = 2; i <= n; ++ i)
    {
        scanf("%d", &x);
        t[i] = x;
        add(x, i);
    }
}
void euler(int x)
{
    E[++ E[0]] = x;
    if(!poz[x])
        poz[x] = E[0];
    lev[x] = lev[t[x]] + 1;
    int p = lst[x];
    while(p)
    {
        euler(vf[p]);
        E[++ E[0]] = x;
        p = Prev[p];
    }
}
void rmq()
{
    int i, j;
    for(i = 1; i <= E[0]; ++ i)
        r[i][0] = E[i];
    for(i = 2; i <= E[0]; ++ i)
        Log[i] = Log[i / 2] + 1;
    for(j = 1; j <= Log[E[0]]; ++ j)
        for(i = 1; i <= E[0]; ++ i)
    {
        r[i][j] = r[i][j - 1];
        if(lev[r[i][j]] > lev[r[i + (1 << (j - 1))][j - 1]])
            r[i][j] = r[i + (1 << (j - 1))][j - 1];
    }
}
void write()
{
    /*for(int i = 1; i <= E[0]; ++ i)
        printf("%d ", E[i]);
    printf("\n");*/
    for(int i = 1; i <= m; ++ i)
    {
        scanf("%d %d", &a, &b);
        a = poz[a];
        b = poz[b];
        if(a > b)
            Swap(a, b);
        L = Log[b - a + 1];
        Sol = r[a][L];
        if(lev[Sol] > lev[r[b - (1 << L) + 1][L]])
            Sol = r[b - (1 << L) + 1][L];
        printf("%d\n", Sol);
    }
}
int main()
{
    read();
    euler(1);
    rmq();
    write();
}