Submission #1308209

#TimeUsernameProblemLanguageResultExecution timeMemory
1308209orzorzorzFireworks (APIO16_fireworks)C++20
100 / 100
342 ms45020 KiB
/** * APIO 2016 - Fireworks * Solution using Slope Trick and Leftist Heaps * Time Complexity: O((N+M) log (N+M)) */ #include <iostream> #include <vector> #include <algorithm> using namespace std; // Leftist Heap Node struct Node { long long val; int dist; // Null Path Length for Leftist property Node *l, *r; Node(long long v) : val(v), dist(0), l(nullptr), r(nullptr) {} }; // Merge two Leftist Heaps (Max Heap) Node* merge(Node* a, Node* b) { if (!a) return b; if (!b) return a; // Max Heap property: larger value at root if (a->val < b->val) swap(a, b); a->r = merge(a->r, b); // Leftist property: dist of left child >= dist of right child if (!a->l || a->l->dist < a->r->dist) swap(a->l, a->r); a->dist = a->r ? a->r->dist + 1 : 0; return a; } // Pop root and return new root Node* pop(Node* root) { if (!root) return nullptr; Node* res = merge(root->l, root->r); delete root; // Clean up memory return res; } const int MAXN = 300005; vector<int> adj[MAXN]; long long edge_weight[MAXN]; Node* heaps[MAXN]; long long total_edge_sum = 0; void dfs(int u) { // Process all children for (int v : adj[u]) { dfs(v); heaps[u] = merge(heaps[u], heaps[v]); } if (u != 1) { // If not root if (adj[u].empty()) { // Leaf Node Logic // Function is |x - w|, slopes change at w and w long long w = edge_weight[u]; heaps[u] = merge(heaps[u], new Node(w)); heaps[u] = merge(heaps[u], new Node(w)); } else { // Internal Node Logic int deg = adj[u].size(); // Pop 'deg - 1' largest breakpoints to flatten slope > 1 to 1 while (deg > 1) { heaps[u] = pop(heaps[u]); deg--; } // Extract the optimal interval [L, R] long long R = heaps[u]->val; heaps[u] = pop(heaps[u]); long long L = heaps[u]->val; heaps[u] = pop(heaps[u]); // Shift by edge weight and push back // The cost function is extended by w heaps[u] = merge(heaps[u], new Node(R + edge_weight[u])); heaps[u] = merge(heaps[u], new Node(L + edge_weight[u])); } } else { // Root Logic int deg = adj[u].size(); // We want the minimum value, which occurs when slope is 0. // The heap currently ends with max slope 'deg'. // We pop 'deg' times to remove all positive slope parts. while (deg > 0) { heaps[u] = pop(heaps[u]); deg--; } // The minimum cost is: (Sum of all weights) - (Sum of remaining breakpoints) // This formula derives from integrating the negative slopes. while (heaps[u]) { total_edge_sum -= heaps[u]->val; heaps[u] = pop(heaps[u]); } } } int main() { // Optimize I/O operations ios_base::sync_with_stdio(false); cin.tie(NULL); int N, M; if (!(cin >> N >> M)) return 0; // Input format: Line i (for i=2...N+M) contains Parent and Weight for (int i = 2; i <= N + M; i++) { int p; long long w; cin >> p >> w; adj[p].push_back(i); edge_weight[i] = w; total_edge_sum += w; } dfs(1); cout << total_edge_sum << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...