Cod sursa(job #2468432)

Utilizator PetrescuAlexandru Petrescu Petrescu Data 5 octombrie 2019 15:35:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <fstream>
#include <iostream>
#include <vector>
#define MAX 100001
#define LOG 32

using namespace std;

int T[MAX], depth[MAX], RMQ[2 * MAX][LOG], poz[MAX];
int n, m;

vector<int> F[MAX];

void DFS(int &k, int nod, int lev)
{
    k++;
    RMQ[k][0] = nod;
    poz[nod] = k;
    depth[nod] = lev;

    for(auto i : F[nod])
    {
        DFS(k, i, lev + 1);
        k++;
        RMQ[k][0] = nod;
    }
}

int main()
{
    int i, j, k, u, q, dist, log2, pow;

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

    fin >> n >> m;

    T[1] = 1;
    for(i = 2; i <= n; i++)
    {
        fin >> T[i];

        F[T[i]].push_back(i);
    }

    k = 0;
    DFS(k, 1, 0);

    for(j = 1; (1 << j) <= k; j++)
        for(i = 1; i + (1 << j) <= k; i++)
        {
            if(depth[RMQ[i][j - 1]] < depth[RMQ[i + (1 << (j - 1))][j - 1]])RMQ[i][j] = RMQ[i][j - 1];
            else RMQ[i][j] = RMQ[i + (1 << (j - 1))][j - 1];
        }

    for(i = 1; i <= m; i++)
    {
        fin >> u >> q;

        if(poz[u] > poz[q])
        {
            u ^= q;
            q ^= u;
            u ^= q;
        }

        dist = poz[q] - poz[u];

        for(log2 = 0, pow = 1; (pow << 1) <= dist; log2++, pow <<= 1);

        if(depth[RMQ[poz[u]][log2]] < depth[RMQ[poz[q] - pow + 1][log2]])fout << RMQ[poz[u]][log2] << '\n';
        else fout << RMQ[poz[q] - pow + 1][log2] << '\n';
    }

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

    return 0;
}