Cod sursa(job #2886598)

Utilizator CristeaCristianCristea Cristian CristeaCristian Data 7 aprilie 2022 22:00:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <fstream>
#include <vector>

using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int NMAX = 200005, KMAX = 20;
int rmq[KMAX][NMAX], euler[NMAX], depth[NMAX], cnt, dfs_num[NMAX], log2[NMAX];
vector <vector<int>> v;
void dfs(int u, int dep)
{
    int i, nod;
    dfs_num[u] = ++cnt;
    depth[u] = dep;
    euler[cnt] = u;
    for(i = 0; i < v[u].size(); i++)
    {
        nod = v[u][i];
        dfs(nod, dep+1);
        euler[++cnt] = u;
    }
}
void compute_rmq()
{
    int i, j;
    for(i = 2; i < NMAX; i++)
        log2[i] = log2[i/2] + 1;
    for(i = 1; i <= cnt; i++)
        rmq[0][i] = euler[i];
    for(j = 1; j < KMAX; j++)
        for(i = 1; i + (1 << j) <= cnt; i++)
        {
            if(depth[rmq[j-1][i]] < depth[rmq[j-1][i + (1 << (j-1))]])
                rmq[j][i] = rmq[j-1][i];
            else
                rmq[j][i] = rmq[j-1][i + (1 << (j-1))];
        }
}
int query_rmq(int l, int r)
{
    int lg = log2[r-l+1];
    if(depth[rmq[lg][l]] < depth[rmq[lg][r-(1 << lg)+1]])
        return rmq[lg][l];
    else
        return rmq[lg][r-(1 << lg)+1];
}
void query(int a, int b)
{
    if(dfs_num[a] > dfs_num[b])
        swap(a, b);
    cout << query_rmq(dfs_num[a], dfs_num[b]) << '\n';
}
int main()
{
    int n, q, i, a, b;
    cin >> n >> q;
    v.resize(n+1);
    for(i = 2; i <= n; i++)
    {
        cin >> a;
        v[a].push_back(i);
    }
    dfs(1, 0);
    compute_rmq();
    while(q--)
    {
        cin >> a >> b;
        query(a, b);
    }
    return 0;
}