Cod sursa(job #2719652)

Utilizator trifangrobertRobert Trifan trifangrobert Data 10 martie 2021 08:34:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.66 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 100000;
const int LMAX = 20;
int N, M;
vector <int> graph[NMAX + 1];
int rmq[LMAX][2 * NMAX + 1], lg[2 * NMAX + 1];
int euler[2 * NMAX + 1], sz, h[NMAX + 1];
int pos[NMAX + 1];

void dfs(int node, int father = 0){
    euler[++sz] = node;
    pos[node] = sz;
    h[node] = h[father] + 1;
    for (auto& son : graph[node]){
        if (son != father){
            dfs(son, node);
            euler[++sz] = node;
        }
    }
}

void BuildRmq(){
    for (int i = 2;i <= sz;++i)
        lg[i] = lg[i >> 1] + 1;
    for (int i = 1;i <= sz;++i)
        rmq[0][i] = i;
    for (int p = 1;(1 << p) <= sz;++p){
        for (int i = 1;i + (1 << p) - 1 <= sz;++i){
            int u = rmq[p - 1][i];
            int v = rmq[p - 1][i + (1 << (p - 1))];
            if (h[euler[u]] < h[euler[v]]){
                rmq[p][i] = u;
            }
            else{
                rmq[p][i] = v;
            }
        }
    }
}

int QueryLca(int u, int v){
    u = pos[u];
    v = pos[v];
    if (u > v)
        swap(u, v);
    int p = lg[v - u + 1];
    u = euler[rmq[p][u]];
    v = euler[rmq[p][v - (1 << p) + 1]];
    if (h[u] < h[v])
        return u;
    else
        return v;
}

int main()
{
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    fin >> N >> M;
    for (int i = 2;i <= N;++i){
        int p;
        fin >> p;
        graph[p].push_back(i);
    }
    dfs(1, 0);
    BuildRmq();
    while (M-- > 0){
        int u, v;
        fin >> u >> v;
        fout << QueryLca(u, v) << "\n";
    }
    fin.close();
    fout.close();
    return 0;
}