Cod sursa(job #2468463)

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

using namespace std;

int depth[MAX], lg[2 * 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;
    }
}

void bitSwap(int &a, int &b)
{
    a ^= b;
    b ^= a;
    a ^= b;
}

void initRMQ(int k)
{
    int i, j;

    lg[1] = 0;
    for(i = 2; i <= k; i++)lg[i] = lg[i / 2] + 1;

    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];
        }
}

int main()
{
    int i, j, nod, k, u, q, a, b, dist, mid, dif;

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

    fin >> n >> m;

    for(i = 2; i <= n; i++)
    {
        fin >> nod;

        F[nod].push_back(i);
    }

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

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

        a = poz[u];
        b = poz[q];

        if(a > b)bitSwap(a, b);

        dist = b - a + 1;
        mid = lg[dist];
        dif = 1 - (1 << mid);

        if(depth[RMQ[a][mid]] < depth[RMQ[b + dif][mid]])fout << RMQ[a][mid] << '\n';
        else fout << RMQ[b + dif][mid] << '\n';
    }

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

    return 0;
}