Cod sursa(job #2280169)

Utilizator papinub2Papa Valentin papinub2 Data 10 noiembrie 2018 12:25:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int Nmax = 100005;

vector<int> A[Nmax];

void DFS (int nod, vector<int>&nivel)
{
    for (auto i = 0; i < A[nod].size(); i++)
    {
        int nod_curent = A[nod][i];
        nivel[nod_curent] = nivel[nod] + 1;
        DFS(nod_curent, nivel);
    }
}

int LCA (int x, int y, vector<int>&nivel, vector<int>&log, vector<vector<int> >&dp)
{
    if (nivel[x] < nivel[y])
        swap(x, y);

    int dif_nivel = nivel[x] - nivel[y];
    for (int i = 0; i <= log[dif_nivel]; i++)
        if ((1<<i) & dif_nivel)
            x = dp[i][x];

    if (x == y)
        return x;

    int rest = log[nivel[y]];
    for (int i = rest; i >= 0; i--)
        if (dp[i][x] != dp[i][y])
            x = dp[i][x], y = dp[i][y];

    return dp[0][x];
}

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

    vector<int> log(n + 1);
    vector<int> nivel(n + 1);

    for (int i = 2; i <= n; i++)
        log[i] = log[i / 2] + 1;

    vector<vector<int> > dp(log[n] + 1, vector<int>(n + 1));

    for (int i = 2; i <= n; i++)
    {
        in >> dp[0][i];
        A[dp[0][i]].push_back(i);
    }

    for (int i = 1; i <= log[n]; i++)
        for (int j = 1; j <= n; j++)
            dp[i][j] = dp[i - 1][dp[i - 1][j]];

    nivel[1] = 1;
    DFS(1, nivel);

    while (T--)
    {
        int x, y;
        in >> x >> y;
        out << LCA(x, y, nivel, log, dp) << '\n';
    }

    return 0;
}