Cod sursa(job #3218208)

Utilizator AlexMihAlexandru Mihailescu AlexMih Data 26 martie 2024 15:27:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.99 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

struct RmqItem{
    int nod;
    int lvl;
};

int p_curent, p_start[200001], max_log, max_bit[200001];
vector<int> v[100001];
RmqItem rmq[200001][20];

void dfs(int nod, int lvl)
{
    int i;
    rmq[++p_curent][0] = {nod, lvl};
    p_start[nod] = p_curent;
    for(i = 0; i < v[nod].size(); i++)
    {
        int vecin = v[nod][i];
        dfs(vecin, lvl + 1);
        rmq[++p_curent][0] = {nod,lvl};
    }
}

void calc_rmq()
{
    int i,p;
    for(p = 1; p <= max_log; p++)
    {
        for(i = 1; i <= p_curent; i++)
        {
            RmqItem st = rmq[i][p-1];
            if(i + (1<<(p-1)) <= p_curent)
            {
                RmqItem dr = rmq[i + (1<<(p-1))][p-1];
                if(st.lvl < dr.lvl)
                {
                    rmq[i][p] = st;
                }
                else
                {
                    rmq[i][p] = dr;
                }
            }
            else
            {
                rmq[i][p] = st;
            }
        }
    }
}

void calc_max_bit()
{
    int i;
    max_bit[1] = 0;
    for(i = 2; i <= p_curent; i++)
    {
        max_bit[i] = max_bit[i/2] + 1;
    }
}

int lca(int x, int y)
{
    int pos_x = p_start[x];
    int pos_y = p_start[y];
    if(pos_x > pos_y){swap(pos_x, pos_y);}
    int l = max_bit[pos_y - pos_x + 1];
    RmqItem st = rmq[pos_x][l];
    RmqItem dr = rmq[pos_y - (1<<l) + 1][l];
    if(st.lvl < dr.lvl)
    {
        return st.nod;
    }
    else
    {
        return dr.nod;
    }
}

int main()
{
    int n,i,q,a,b;
    f>>n>>q;
    for(i = 2; i <= n; i++)
    {
        f>>a;
        v[a].push_back(i);
    }
    p_curent = 0;
    dfs(1, 1);
    max_log = 32 - __builtin_clz(p_curent) - 1;
    calc_rmq();
    calc_max_bit();
    for(i = 1; i <= q; i++)
    {
        f>>a>>b;
        g<<lca(a,b)<<'\n';
    }
    return 0;
}