Cod sursa(job #1656849)

Utilizator iulian_f2kGuraliuc Iulian iulian_f2k Data 19 martie 2016 21:56:22
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100005
using namespace std;

vector<vector<int> > G;
vector<int> E, H, FirstPosition, aux, logg;
vector<vector<int> > RMQ;
int N, M;

void read();
void Euler(int node, int h);
void preprocesare();
int log2(int N);
int Query(int a, int b);
int LCA(int a, int b);

int main()
{
    read();
    Euler(1, 0);
    preprocesare();
    int a, b;
    for(int i=1; i<=M; ++i) {
        scanf("%d%d", &a, &b);
        if(a == b)
            cout<<a<<'\n';
        else
        cout<<LCA(a, b)<<'\n';
    }
    return 0;
}
int LCA(int a, int b)
{
    return Query(FirstPosition[a], FirstPosition[b]);
}

int Query(int a, int b)
{
    if(a > b) {
        a += b;
        b = a - b;
        a -= b;
    }
    int k = logg[b-a+1];
    if(H[RMQ[a][k]] < H[RMQ[b-(1<<k)+1][k]])
        return RMQ[a][k];
    else
        return RMQ[b-(1<<k)+1][k];
}
void preprocesare()
{
    logg.push_back(0);
    logg.push_back(0);
    logg.push_back(1);
    for(int i=3, carry = 1; i<=2*E.size()+10; ++i, ++carry) {
        logg.push_back(0);
        logg[i] = logg[i-1];
        if(carry>>(logg[i-1]) & 1)
            logg[i]++, carry = 0;
    }
    int maxLog = logg[E.size()-1];
    aux.assign(maxLog+2, 0);
    RMQ.assign(2 * E.size(), aux);
    for(int i=0; i<E.size(); ++i)
        RMQ[i][0] = E[i];
    for(int k=1; k<=maxLog; ++k)
        for(int i=0; i<E.size(); ++i)
            if(H[RMQ[i][k-1]] < H[RMQ[i+(1<<(k-1))][k-1]])
                RMQ[i][k] = RMQ[i][k-1];
            else
                RMQ[i][k] = RMQ[i+(1<<(k-1))][k-1];
}
void Euler(int node, int h)
{
    E.push_back(node);
    H[node] = h;
    FirstPosition[node] = E.size()-1;
    for(int i=0; i<G[node].size(); ++i) {
        Euler(G[node][i], h+1);
        E.push_back(node);
    }
}
void read()
{
    freopen("lca.in", "rt", stdin);
    freopen("lca.out", "wt", stdout);
    scanf("%d%d", &N, &M);
    H.assign(N+2, 0);
    FirstPosition.assign(N+2, 0);
    G.assign(N+2, vector<int>());
    int b;
    for(int i=2; i<=N; ++i)
    {
        scanf("%d", &b);
        G[b].push_back(i);
    }
}