Cod sursa(job #2833891)

Utilizator Stefan_DomuncoStefan Domunco Stefan_Domunco Data 15 ianuarie 2022 21:42:14
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.09 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 1e5 + 5;
int n, q, depth[2 * NMAX + 5];
int rmq[NMAX][22], peuler[2 * NMAX + 5], nrpeuler;
int firstPos[NMAX];
vector <int> g[NMAX];
bitset <NMAX> viz;

void DFS(int node, int ad)
{
    if(firstPos[node] == 0)
        firstPos[node] = nrpeuler + 1;

    peuler[++nrpeuler] = node;
    int i;
    for(i = 0; i < g[node].size(); ++i)
    {
        if(!viz[g[node][i]])
        {
            viz[g[node][i]] = 1;
            depth[g[node][i]] = ad + 1;
            DFS(g[node][i], ad + 1);
            peuler[++nrpeuler] = node;
        }
    }
}

inline void build_rmq()
{
    int i, j;
    for(i = 1; i <= nrpeuler; ++i)
        rmq[i][0] = peuler[i];

    for(j = 1; (1 << j) <= nrpeuler; ++j)
    {
        for(i = 1; i + (1 << j) - 1 <= nrpeuler; ++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];
        }
    }
}

inline int query_rmq(int a, int b)
{

    if(firstPos[b] < firstPos[a])
        swap(a, b);

    int lung = log2(firstPos[b] - firstPos[a] + 1);

    if(depth[rmq[firstPos[a]][lung]] < depth[rmq[firstPos[b] - (1 << lung) + 1][lung]])
        return rmq[firstPos[a]][lung];
    else return rmq[firstPos[b] - (1 << lung) + 1][lung];
}
int main()
{
    int i;
    fin >> n >> q;
    for(i = 2; i <= n; ++i)
    {
        int node;
        fin >> node;
        g[node].push_back(i);
        g[i].push_back(node);
    }

    viz[1] = 1;
    DFS(1, 1);

//    for(i = 1; i <= nrpeuler; ++i)
//        fout << peuler[i] << ' ';

    build_rmq();

//    int j;
//    for(j = 0; (1 << j) <= nrpeuler; ++j)
//    {
//        for(i = 1; i + (1 << j) - 1 <= nrpeuler; ++i)
//            fout << rmq[i][j] << ' ';
//        fout << '\n';
//    }

    for(i = 1; i <= q; ++i)
    {
        int a, b;
        fin >> a >> b;
        fout << query_rmq(a, b) << '\n';
    }

    return 0;
}