Skip to Content

Lomsat gelral

Análisis oficial 

Implementación

Como se explica en el análisis oficial, cuando usamos fusión small-to-large en estructuras de datos como conjuntos y mapas, optimizamos la cantidad de operaciones de O(N2logN)\mathcal{O}(N^2 \log N) a O(Nlog2N)\mathcal{O}(N \log^2 N). Podemos aprovechar esto para guardar todo tipo de información relacionada con los colores, su suma y sus ocurrencias.

Complejidad temporal: O(Nlog2N)\mathcal{O}(N \log^2 N)

#include <bits/stdc++.h> using namespace std; using ll = long long; const int MAX_N = 1e5; array<ll, MAX_N> color; array<ll, MAX_N> ans; vector<int> g[MAX_N]; // col_count[i][j] = number of occurrences of color j in i map<ll, ll> col_count[MAX_N]; // sum_occur[i][j] = sum of colors having occurrence j in subtree i map<ll, ll> sum_occur[MAX_N]; void dfs(int node, int p) { // initialize this node col_count[node][color[node]] += 1; sum_occur[node][1] += color[node]; for (int i : g[node]) { if (i == p) { continue; } dfs(i, node); // retrieve the biggest map so we have less to merge if (col_count[node].size() < col_count[i].size()) { col_count[node].swap(col_count[i]); sum_occur[node].swap(sum_occur[i]); } // update bigger map with information from smaller map for (auto [col, cnt] : col_count[i]) { // remove old occurrences if (col_count[node].count(col)) { sum_occur[node][col_count[node][col]] -= col; } // add new occurrences col_count[node][col] += cnt; sum_occur[node][col_count[node][col]] += col; } } // retrieve the sum with the biggest j ans[node] = sum_occur[node].rbegin()->second; } int main() { int n; cin >> n; for (int i = 0; i < n; i++) { cin >> color[i]; } for (int i = 0; i < n - 1; i++) { int u, v; cin >> u >> v; g[--u].push_back(--v); g[v].push_back(u); } dfs(0, 0); for (int i = 0; i < n; i++) { cout << ans[i] << " "; } }