Cod sursa(job #1547363)

Utilizator fromzerotoheroFROM ZERO fromzerotohero Data 9 decembrie 2015 13:55:25
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <iostream>
#include <fstream>
#include <vector>

#define nmax 100001

using namespace std;

int n, m;
int x, y;
int RMQ[18][2*nmax], POS[18][2*nmax];
int Euler[2*nmax], Exp[2*nmax];
int Nivel[nmax], T[nmax], firstS[nmax];
vector <int> arb[nmax];

void buildEuler(int nod, int niv)
{
    Euler[++Euler[0]] = nod;
    Nivel[nod] = niv; // The level of the 'Euler[0]'th node

    firstS[nod] = Euler[0]; // first appearance of node 'nod' in the Euler sequence

    for (int i = 0; i < arb[nod].size(); i++)
        buildEuler(arb[nod][i], niv + 1),
        Euler[++Euler[0]] = nod;
}

void preProcess()
{

    Exp[1] = 0;
    for (int i = 2; i <= Euler[0]; i++)
        Exp[i] = 1 + Exp[i/2];

    for (int i = 1; i <= Euler[0]; i++)
        RMQ[0][i] = Nivel[Euler[i]],
        POS[0][i] = i; // The position of node 'Euler[i]' in the Euler sequence

    for (int i = 1; i <= Exp[Euler[0]]; i++)
        for (int j = 1; j <= Euler[0]; j++)
        {
            int st = j;
            int dr = j + (1<<i) - 1;
            int mid = dr - (1<<(i-1)) + 1;

            if (RMQ[i-1][st] < RMQ[i-1][mid])
            {
                RMQ[i][j] = RMQ[i-1][st];
                POS[i][j] = POS[i-1][st];
            }
            else
            {
                RMQ[i][j] = RMQ[i-1][mid];
                POS[i][j] = POS[i-1][mid];
            }
        }

}

int main()
{

    ifstream fi("lca.in");
    ofstream fo("lca.out");

    fi >> n >> m;
    for (int i = 2; i <= n; i++)
        fi >> T[i], // lista de tati a arborelui
        arb[T[i]].push_back(i);

    buildEuler(1, 0);

    preProcess();

    for (int i = 1; i <= m; i++)
    {
        fi >> x >> y;

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

        int len = (y - x + 1);
        int p = Exp[len];

        int mid = y - (1<<p) + 1;

        int ancestor = RMQ[p][x];
        int posAncestor = POS[p][x];

        if (RMQ[p][mid] < ancestor)
            posAncestor = POS[p][mid];

        fo << Euler[posAncestor] << "\n";
    }

    fi.close();
    fo.close();

    return 0;
}