Cod sursa(job #2262004)

Utilizator preda.andreiPreda Andrei preda.andrei Data 16 octombrie 2018 21:18:24
Problema Lowest Common Ancestor Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.87 kb
#include <fstream>
#include <vector>

using namespace std;

struct Node
{
    int time = 0;
    vector<int> ancestors;
    vector<int> sons;
};

using Tree = vector<Node>;

void FindAncestors(Tree &t, int node)
{
    auto anc = t[node].ancestors[0];
    auto order = 0;

    while (order < (int)t[anc].ancestors.size()) {
        auto other_anc = t[anc].ancestors[order];
        t[node].ancestors.push_back(other_anc);
        anc = other_anc;
        order += 1;
    }
}

void Dfs(Tree &t, int node)
{
    if (!t[node].ancestors.empty()) {
        FindAncestors(t, node);
    }
    for (const auto &son : t[node].sons) {
        Dfs(t, son);
    }

    static auto time = 0;
    t[node].time = (time += 1);
}

int GetNearAncestor(const Tree &t, int node, int max_time)
{
    auto index = 0;
    auto power = (1 << 17);

    while (power > 0) {
        auto next_index = index + power;
        power >>= 1;

        if (next_index < (int)t[node].ancestors.size()) {
            auto anc = t[node].ancestors[next_index];
            if (t[anc].time <= max_time) {
                index = next_index;
            }
        }
    }
    return t[node].ancestors[index];
}

int GetLca(const Tree &t, int a, int b)
{
    if (t[a].time > t[b].time) {
        swap(a, b);
    }

    while (t[a].time < t[b].time) {
        a = GetNearAncestor(t, a, t[b].time);
    }
    return a;
}

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

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

    Tree tree(nodes);
    for (int i = 1; i < nodes; i += 1) {
        int father;
        fin >> father;

        tree[father - 1].sons.push_back(i);
        tree[i].ancestors.push_back(father - 1);
    }

    Dfs(tree, 0);

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

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

    return 0;
}