Cod sursa(job #2608105)

Utilizator copanelTudor Roman copanel Data 30 aprilie 2020 16:36:14
Problema Atac Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <iostream>
#include <fstream>
#include <vector>

struct node {
    std::vector<int> children;
    int parent;
    int first_euler;
    int level;
    int points;
} nodes[32001];
int euler[64002];
int rmq[17][64002];
int log2[64002];

void dfs_euler(int node) {
    static int euler_i;

    euler[++euler_i] = node;
    nodes[node].first_euler = euler_i;
    for (const int child_id : nodes[node].children) {
        auto& child = nodes[child_id];
        if (child.first_euler == 0) {
            child.level = nodes[node].level + 1;
            dfs_euler(child_id);
            euler[++euler_i] = node;
        }
    }
}

inline void compute_log2(int n) {
    log2[1] = 0;
    for (int i = 2; i <= 2 * n - 1; i++) {
        log2[i] = log2[i / 2] + 1;
    }
}

int lca(int n, int a, int b) {
    int p = nodes[a].first_euler, q = nodes[b].first_euler;
    if (p > q) {
        std::swap(p, q);
    }
    int l = log2[q - p + 1];
    int st = rmq[l][p + (1 << l) - 1];
    int dr = rmq[l][q];
    if (nodes[st].level < nodes[dr].level) {
        return st;
    } else {
        return dr;
    }
}

int main() {
    std::ifstream fin("concurs.in");
    std::ofstream fout("concurs.out");
    int n, m;

    fin >> n >> m;
    for (int i = 1; i <= n; i++) {
        fin >> nodes[i].points;
    }
    for (int i = 0; i < n - 1; i++) {
        int parent, child;
        fin >> parent >> child;
        nodes[child].parent = parent;
        nodes[parent].children.push_back(child);
    }

    int root = 1;
    while (root <= n && nodes[root].parent > 0) {
        root++;
    }

    compute_log2(n);
    dfs_euler(root);

    for (int j = 1; j <= 2 * n - 1; j++) {
        rmq[0][j] = euler[j];
    }
    for (int i = 1; (1 << i) <= 2 * n - 1; i++) {
        for (int j = 1; j <= 2 * n - 1; j++) {
            int st = rmq[i - 1][j - (1 << (i - 1))];
            int dr = rmq[i - 1][j];
            if (nodes[st].level < nodes[dr].level) {
                rmq[i][j] = st;
            } else {
                rmq[i][j] = dr;
            }
        }
    }

    int maxp = 0, maxa, maxb;
    for (int i = 0; i < m; i++) {
        int a, b;
        fin >> a >> b;
        int node = lca(n, a, b);
        if (nodes[node].points > maxp) {
            maxp = nodes[node].points;
            maxa = a;
            maxb = b;
        } else if (nodes[node].points == maxp &&
            (a < maxa || (a == maxa && b < maxb))) {
            maxa = a;
            maxb = b;
        }
    }
    fout << maxp << ' ' << maxa << ' ' << maxb;
    return 0;
}