Cod sursa(job #3199976)

Utilizator devilexeHosu George-Bogdan devilexe Data 3 februarie 2024 10:11:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.47 kb
#include <bits/stdc++.h>
using namespace std;

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

const int MAXN = 1e5, log2_MAXN = 17;
int N, M;
vector<int> G[MAXN + 1];
bool viz[MAXN + 1];
int idx[MAXN + 1];
int rmq[log2_MAXN + 1][2 * MAXN + 1];
int depth[MAXN + 1];
int sz = 0;

void dfs(int nod, int k)
{
    viz[nod] = 1;
    //if(nod != 1 && !idx[nod])
    idx[nod] = sz;
    rmq[0][sz++] = nod;
    depth[nod] = k;
    for(const auto& x : G[nod])
    {
        if(!viz[x]) {
            dfs(x, k + 1);
            rmq[0][sz++] = nod;
        }
    }
}

int main()
{
    fin >> N >> M;
    int a, b;
    for(int i = 2; i <= N; ++i) {
        fin >> a;
        G[a].push_back(i);
    }
    dfs(1, 0);

    // pornim rmq
    for (int k = 1; (1 << k) < sz; ++k)
    {
        for (int i = 0; i + (1 << k) < sz; ++i)
        {
            if (depth[rmq[k - 1][i]] < depth[rmq[k - 1][i + (1 << (k - 1))]])
                rmq[k][i] = rmq[k - 1][i];
            else
                rmq[k][i] = rmq[k - 1][i + (1 << (k - 1))];
        }
    }
    
    while(M--)
    {
        fin >> a >> b;
        int i = idx[a], j = idx[b];
        if(i > j)
            swap(i, j);
        int len = j - i + 1;
        int shiftk = 0;
        while(len > 1)
            len >>= 1,
            ++shiftk;
        int chk1 = rmq[shiftk][i], chk2 = rmq[shiftk][j-(1 << shiftk)+1];
        if(depth[chk1] < depth[chk2])
            fout << chk1 << '\n';
        else
            fout << chk2 << '\n';
    }
    return 0;
}