Cod sursa(job #591721)

Utilizator darrenRares Buhai darren Data 25 mai 2011 11:51:19
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 kb
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

typedef vector<int> VI;

int N, M;
VI V[100002];
int RMQ[20][200002];
int Niv[200002], Is[200002], Enter[200002], sizeE;
int Lg[200002];

void makeE(int x, int level)
{
    Enter[x] = ++sizeE;
    Niv[sizeE] = level;
    Is[sizeE] = x;

    for (VI::iterator it = V[x].begin(); it != V[x].end(); ++it)
    {
        makeE(*it, level + 1);
        Niv[++sizeE] = level;
        Is[sizeE] = x;
    }
}

int main()
{
    ifstream fin("lca.in");
    ofstream fout("lca.out");

    for (int i = 2; i <= 200000; ++i)
        Lg[i] = Lg[i >> 1] + 1;

    fin >> N >> M;
    for (int i = 2, tata; i <= N; ++i)
    {
        fin >> tata;
        V[tata].push_back(i);
    }

    makeE(1, 0);

    for (int i = 1; i <= sizeE; ++i)
        RMQ[0][i] = i;
    for (int s = 1; (1 << s) <= sizeE; ++s)
        for (int i = 1; i <= sizeE; ++i)
        {
            RMQ[s][i] = RMQ[s - 1][i];
            if (i + (1 << s) - 1 <= sizeE && Niv[RMQ[s - 1][i + (1 << s) - 1]] < Niv[RMQ[s][i]])
                RMQ[s][i] = RMQ[s - 1][i + (1 << s) - 1];
        }

    for (int i = 1, nod1, nod2; i <= M; ++i)
    {
        fin >> nod1 >> nod2;
        if (Enter[nod1] > Enter[nod2])
            swap(nod1, nod2);

        int k = Lg[Enter[nod2] - Enter[nod1] + 1];
        if (Niv[RMQ[k][Enter[nod1]]] < Niv[RMQ[k][Enter[nod2] - (1 << k) + 1]])
            fout << Is[RMQ[k][Enter[nod1]]] << '\n';
        else
            fout << Is[RMQ[k][Enter[nod2] - (1 << k) + 1]] << '\n';
    }

    fin.close();
    fout.close();
}