Cod sursa(job #2576852)

Utilizator Bogdan2728Iamnitchi Bogdan Bogdan2728 Data 7 martie 2020 00:07:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include <bits/stdc++.h>
#define MAXN    100005
#define LOG2    20
using namespace std;

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

int N, M;
int depth[MAXN], first[MAXN];
int RMQ[LOG2][2*MAXN], logtable[2*MAXN];
vector <int> euler;
vector <int> ADC[MAXN];

void DFS(int vertex, int parent) {
    first[vertex] = euler.size();
    depth[vertex] = depth[parent]+1;
    euler.push_back(vertex);
    for (auto &it:ADC[vertex]) {
        if (it == parent)
            continue;
        DFS(it, vertex);
        euler.push_back(vertex);
    }
}
void computeRMQ() {
    for (int i=2; i<2*MAXN; i++)
        logtable[i] = logtable[i>>1] + 1;
    for (int i=0; i<euler.size(); i++)
        RMQ[0][i] = euler[i];
    for (int i=1; i<LOG2; ++i)
        for (int j=0, k=(1<<i); k<euler.size(); j++, k++)
            RMQ[i][j] = (depth[RMQ[i-1][j]] < depth[RMQ[i-1][j + (1<<(i-1))]] ? RMQ[i-1][j] : RMQ[i-1][j + (1<<(i-1))]);
}
int LCA(int u, int v) {
    if (u == v)
        return u;
    int st = first[u];
    int dr = first[v];
    if (st > dr)
        swap(st, dr);
    int len = logtable[dr-st+1];
    int c1 = RMQ[len][st];
    int c2 = RMQ[len][dr-(1<<len)+1];
    if (depth[c1] < depth[c2])
        return c1;
    return c2;
}

int main()
{
    input >> N >> M;
    for (int i=1, x; i<N; i++)
    {
        input >> x;
        ADC[x].push_back(i+1);
        ADC[i+1].push_back(x);
    }

    DFS(1,0);
    computeRMQ();

    for (int i=1, x, y; i<=M; i++)
    {
        input >> x >> y;
        output << LCA(x, y) << '\n';

    }
    return 0;
}