Cod sursa(job #2397896)

Utilizator preda.andreiPreda Andrei preda.andrei Data 4 aprilie 2019 21:04:51
Problema Lowest Common Ancestor Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.74 kb
#include <cmath>
#include <fstream>
#include <vector>

using namespace std;

struct Node
{
    vector<int> sons;
    int father = -1;
    int ancestor = -1;

    int depth = 0;
    int bucket;
};

using Tree = vector<Node>;

#include <iostream>
void Dfs(Tree &t, int node, int level, const int kBucketDepth)
{
    static auto bucket_id = 0;
    auto next_level = level + 1;

    if (level >= kBucketDepth) {
        next_level = 0;
        bucket_id += 1;
        t[node].ancestor = t[node].father;
        t[node].bucket = (bucket_id += 1);
    }

    for (const auto &next : t[node].sons) {
        t[next].depth = t[node].depth + 1;
        t[next].bucket = t[node].bucket;
        t[next].ancestor = t[node].ancestor;
        t[next].father = node;
        Dfs(t, next, next_level, kBucketDepth);
    }
}

int SimpleLca(const Tree &t, int a, int b)
{
    while (a != b) {
        if (t[a].depth >= t[b].depth) {
            a = t[a].father;
        } else {
            b = t[b].father;
        }
    }
    return a;
}

int FindLca(const Tree &t, int a, int b)
{
    while (t[a].bucket != t[b].bucket) {
        if (t[a].depth >= t[b].depth) {
            a = t[a].ancestor;
        } else {
            b = t[b].ancestor;
        }
    }
    return SimpleLca(t, a, b);
}

int main()
{
    ifstream fin("lca.in");
    ofstream fout("lca.out");

    int nodes, queries;
    fin >> nodes >> queries;

    Tree tree(nodes);
    for (auto i = 1; i < nodes; i += 1) {
        int father;
        fin >> father;
        tree[father - 1].sons.push_back(i);
    }

    Dfs(tree, 0, 0, sqrt(nodes));

    for (auto i = 0; i < queries; i += 1) {
        int a, b;
        fin >> a >> b;

        auto res = FindLca(tree, a - 1, b - 1);
        fout << res + 1 << "\n";
    }

    return 0;
}