Cod sursa(job #835183)

Utilizator UnforgivenMihai Catalin Botezatu Unforgiven Data 15 decembrie 2012 20:31:02
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include <fstream>
#include <cstdio>
#include <vector>
#define MAX_SIZE 100001

using namespace std;


vector <int> arb[MAX_SIZE];
int rmq[30][MAX_SIZE << 2];
int euler[MAX_SIZE << 2];
int L[MAX_SIZE << 2];
int K = 0;
int aparitie[MAX_SIZE];
char select[MAX_SIZE];
int lg[MAX_SIZE];



void swap(int &a , int &b)
{
    int aux  = a;
    a = b;
    b = aux;
}

void dfs(int nod , int nivel)
{
    K++;
    select[nod] = 1;
    euler[K] = nod;
    L[K] = nivel;
    aparitie[nod] = K;

    rmq[0][K] = K;
    for (int i =0;i<arb[nod].size();i++)
    {
        if (select[arb[nod][i]] != 1)
        {

            dfs(arb[nod][i] , nivel + 1);
            K++;
            euler[K] = nod;
            L[K] = nivel;
            rmq[0][K] = K;
        }
    }

}

void RMQ()
{
    for(int i = 2; i <= K; ++i)
    {
        lg[i] = lg[i >> 1] + 1;
    }


    int logK = 0;
    while ((1 << logK) < K)
    {
        logK ++;
    }

    for (int i = 1;i <= logK;i++)
    for (int j = 1; j <= K - (1 << i);j++)
    {

        if (L[rmq[i-1][j]] < L[rmq[i-1][j + (1 << (i-1))]] )
        {
            rmq[i][j] = rmq[i-1][j];
        }
        else
        {
            rmq[i][j] = rmq[i-1][j + (1 << (i-1))];
        }
    }
}

int lca(int start , int end)
{
    int x = aparitie[start];
    int y = aparitie[end];

    if (x > y ) swap(x,y);

    int dif = y - x + 1;
    int h = lg[dif];
    int rest = dif - (1 << h);
    if (L[rmq[h][x]] < L[rmq[h][x + rest]] )
    {
            return euler[rmq[h][x]];
    }
    else
    {
            return euler[rmq[h][y+1 - (1 << h)]];
    }



}


int main()
{
    ifstream input("lca.in");
    ofstream output("lca.out");
    int N , Q;
    input >> N >> Q;

    for (int i =1;i<N;i++)
    {
        int x;
        input >> x;
        arb[x].push_back(i+1);
        arb[i+1].push_back(x);


    }
    dfs(1,0);
    RMQ();

    for (int i = 0 ;i < Q;i++)
    {
        int t , p;
        input >> t >> p;
        output << lca(t,p) << "\n";
    }
    input.close();
    output.close();

    return 0;
}