Cod sursa(job #3003295)

Utilizator velciu_ilincavelciu ilinca velciu_ilinca Data 15 martie 2023 17:23:37
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.91 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");

const int nmax = 100000;
const int log1 = log2(nmax);
vector<int>g[nmax + 1];
int nivel[nmax + 1];
int poz[nmax + 1];
int dp[log1 + 1][nmax + 1];
vector<int>v;
int n,m;
int pozi = 0;

void dfs(int node, int level)
{
    v.push_back(node);

    nivel[node] = level;
    level++;

    pozi++;
    poz[node] = pozi;

    for(int i = 0; i < g[node].size(); i++)
    {
        int vecin = g[node][i];
        if(nivel[vecin] == 0)
        {
            dfs(vecin,level);
            pozi++;
        }

        v.push_back(node);
        poz[node] = pozi;
    }
}
void build_rmq()
{
    for(int i = 0; i < v.size(); i++)
        dp[0][i] = v[i];

    int length = v.size();
    int l2 = log2(length);

    for(int i = 1; i <= l2; i++)
        for(int j = 1; j <= length; j++)
        {
            if(nivel[dp[i - 1][j]] < nivel[dp[i - 1][j + (1<<(i - 1))]])
                dp[i][j] = dp[i - 1][j];
            else
                dp[i][j] = dp[i - 1][j + (1<<(i - 1))];
        }
}
int find_ancestor(int x, int y)
{
    int pozx = poz[x] - 1;
    int pozy = poz[y] - 1;
    if(pozx > pozy)
        swap(pozx, pozy);

    int length = pozy - pozx + 1;
    int l2 = log2(length);
    int lint1 = (1<<l2);

    int finali = 0x3f3f3f3f;
    int cmp = dp[l2][pozx];
    int cmp2 = dp[l2][pozy - lint1 + 1];

    if(nivel[cmp] < finali)
        finali = cmp;
    if(nivel[cmp2] < finali)
        finali = cmp2;

    return finali;
}
int main()
{
    in>>n>>m;
    for(int i = 1; i <= n - 1; i++)
    {
        int x;
        in>>x;
        g[x].push_back(i + 1);
    }
    dfs(1,1);

    build_rmq();
    for(int i = 1; i <= m ; i++)
    {
        int x,y;
        in>>x>>y;
        out<<find_ancestor(x,y)<<'\n';
    }

    return 0;
}