Cod sursa(job #3293253)

Utilizator Manolea_Teodor_StefanManolea Teodor Stefan Manolea_Teodor_Stefan Data 11 aprilie 2025 02:59:59
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include <bits/stdc++.h>
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt")

//#define fin cin
//#define fout cout

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int nmax = 1e5+1;
int n,m;
array<int,2*nmax> exponent,t,last;
vector<int> g[nmax];
struct cv{
    int depth,node;
    static cv min(cv a, cv b){
        return ((a.depth < b.depth) ? a : b);
    }
} rmq[32][nmax],info[nmax];
int gindex;
void process(int node, int depth) {
    info[++gindex] = {depth,node};
    last[node] = gindex;
}
void dfs(int node = 1, int depth = 1) {
    process(node,depth);
    for (auto x : g[node]) {
        dfs(x,depth+1);
        process(node,depth);
    }
}

int query(int l, int r) {
    int e = exponent[r - l + 1];
    return cv::min(rmq[e][l],rmq[e][r - (1<<e) + 1]).node;
}
int lca(int x, int y) {
    int l = last[x];
    int r = last[y];
    if (l > r) swap(l,r);
    return query(l,r);
}

int main() {
    fin >> n >> m;
    for (int i = 2; i <= n; i++) {
        int x; fin >> x;
        g[x].push_back(i);
    }
    dfs();
    for (int i = 2; i <= gindex; i++)
        exponent[i] = 1 + exponent[i/2];
    for (int i = 1; i <= gindex; i++) rmq[0][i] = info[i];
    for (int p = 1; (1<<p) <= gindex; p++) {
        for (int i = 1; i <= gindex; i++) {
            int j = min(gindex,i+(1<<(p-1)));
            rmq[p][i] = cv::min(rmq[p-1][i],rmq[p-1][j]);
        }
    }
    while (m--) {
        int x,y;
        fin >> x >> y;
        fout << lca(x,y) << '\n';
    }

    return 0;
}