Cod sursa(job #3131210)

Utilizator LucaMuresanMuresan Luca Valentin LucaMuresan Data 19 mai 2023 15:48:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.37 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 1e5;
const int p2[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144};

int p[NMAX + 5];
int depth[NMAX + 5];
int rmq[18][NMAX + NMAX + 5];
int lg2[NMAX + NMAX + 5];
int tin[NMAX + 5];

vector<int>g[NMAX + 5];

int t = 0;

void dfs (int u)
{
    depth[u] = depth[p[u]] + 1;
    tin[u] = ++t;
    rmq[0][t] = u;
    for (const auto &v : g[u])
    {
        dfs(v);
        rmq[0][++t] = u;
    }
}

#define compare(a,b) (depth[a] < depth[b]? a : b)

int lca (int u, int v)
{
    u = tin[u], v = tin[v];
    if (u > v) swap(u, v);
    int k = lg2[v - u + 1];
    return compare(rmq[k][u], rmq[k][v - p2[k] + 1]);
}

int main()
{
    int n, q;
    in >> n >> q;

    for (int i=2; i<=n; i++)
        {
            in >> p[i];
            g[p[i]].push_back(i);
        }

    dfs(1);
    int m = (n << 1);
    for (int i=2; i<m; i++)
        lg2[i] = lg2[i >> 1] + 1;

    for (int j=1; p2[j] < m; j++)
    {
        for (int i=1; i+p2[j]-1<m; i++)
        {
            rmq[j][i] = compare(rmq[j-1][i], rmq[j-1][i+p2[j-1]]);
        }
    }

    while (q--)
    {
        int u, v;
        in >> u >> v;
        out << lca(u, v) << '\n';
    }

    return 0;
}