Cod sursa(job #2222148)

Utilizator andreistanStan Andrei andreistan Data 16 iulie 2018 15:57:12
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.9 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int NMAX = 100001;
struct nod
{
    int x;
    nod *leg;
};
nod *v[NMAX];

int N, M, h;
int st[NMAX];
int eu[NMAX], primviz[NMAX];
int D[18][NMAX];
bool viz[NMAX];

void add(nod *&dest, int val)
{
    nod *p;
    p = new nod;
    p ->x = val;
    p->leg = dest;
    dest = p;
}

void Euler(int x)
{
    st[++h] = x;
    //cout << st[h] << ' ';
    //nivel[eu[0]]=h;
    eu[++eu[0]] = st[h];
    D[0][eu[0]] = h;
    if(!viz[x])
    {
        primviz[x] = eu[0];
        viz[x] = 1;
    }
    for(nod *q = v[x]; q != NULL; q = q->leg)
    {
        Euler(q->x);
        h--;
        //cout << st[h] << ' ';
        //nivel[eu[0]]=h;
        eu[++eu[0]] = st[h];
        D[0][eu[0]] = h;
    }
}

void precalc()
{
    for(int i = 1; (1 << i) <= eu[0]; i++)
    {
        int bound = eu[0] - (1 << i) + 1; // N - 2^j + 1
        for(int j = 1; j <= bound; j++)
            D[i][j] = min(D[i - 1][j], D[i - 1][j + (1 << (i - 1))]);
    }
}

int RMQ(int x, int y)
{
    //RMQ(x,y)=min(D[k][x],D[k][y - 2^k + 1])
    //2^k <= y-x, k maxim
    if(x == y)
        return D[0][x];
    int dif = y - x;
    int k = 0;
    for(; 1 << k <= dif; k++);
    k--;
    return min(D[k][x], D[k][y - (1 << k) + 1]);
}

int main()
{
    f >> N >> M;
    for(int i = 2; i <= N; i++)
    {
        int t;
        f >> t;
        //T[i+1]=t;
        add(v[t], i);
    }
    Euler(1);
    precalc();
    while(M--)
    {
        int x, y;
        f >> x >> y;
        x=primviz[x];
        y=primviz[y];
        if(x>y)
            swap(x,y);
        int nivmin = RMQ(x,y);
        for(int i = x; i <= y; i++)
            if(D[0][i] == nivmin)
            {
                g << eu[i] << '\n';
                break;
            }
    }
    return 0;
}