Cod sursa(job #2553476)

Utilizator trifangrobertRobert Trifan trifangrobert Data 22 februarie 2020 00:34:17
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 100005;
int N, M;
int euler[2 * NMAX], len;
int h[NMAX], pos[NMAX];
int rmq[20][2 * NMAX], lg[2 * NMAX];
vector <int> graph[NMAX];

void dfs(int node, int father)
{
    h[node] = h[father] + 1;
    euler[++len] = node;
    pos[node] = len;
    for (auto& x : graph[node])
    {
        dfs(x, node);
        euler[++len] = node;
    }
}

void BuildRMQ()
{
    int K = len;
    for (int i = 2;i <= K;++i)
        lg[i] = lg[i >> 1] + 1;
    for (int i = 1;i <= K;++i)
        rmq[0][i] = i;
    for (int p = 1;(1 << p) <= K;++p)
        for (int i = 1;i + (1 << p) - 1 <= K;++i)
        {
            int u, v;
            u = rmq[p - 1][i];
            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 x;
        fin >> x;
        graph[x].push_back(i);
    }
    dfs(1, 0);
    BuildRMQ();
    for (int i = 1;i <= M;++i)
    {
        int u, v;
        fin >> u >> v;
        fout << QueryLCA(u, v) << "\n";
    }
    fin.close();
    fout.close();
    return 0;
}