Submission #1246736

#TimeUsernameProblemLanguageResultExecution timeMemory
1246736idk_anything_i_guessSafety (NOI18_safety)C++20
0 / 100
23 ms8812 KiB
#include <iostream> #include <vector> #include <numeric> #include <algorithm> // Function to set up fast I/O void setup_io() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); } // Solves the L1 Isotonic Regression problem for a non-decreasing sequence using PAVA. // It finds the optimal block partitions using L2 PAVA (mean-based), which is O(N), // and then calculates the medians for each block to get the L1 solution. std::vector<long long> compute_isotonic_nondecreasing(const std::vector<long long>& y) { int n = y.size(); if (n == 0) { return {}; } // Active set for PAVA, stores pairs of (mean, weight) for each pool. std::vector<std::pair<double, int>> pools; for (long long val : y) { pools.push_back({(double)val, 1}); // Merge pools as long as the non-decreasing property is violated. while (pools.size() > 1 && pools.back().first < pools[pools.size() - 2].first) { auto p2 = pools.back(); pools.pop_back(); auto p1 = pools.back(); pools.pop_back(); double merged_mean = (p1.first * p1.second + p2.first * p2.second) / (p1.second + p2.second); int merged_weight = p1.second + p2.second; pools.push_back({merged_mean, merged_weight}); } } // Reconstruct the final solution vector from the pools. std::vector<long long> result(n); int current_idx = 0; for (const auto& pool : pools) { int weight = pool.second; // Create a temporary vector for the elements in the current block. std::vector<long long> block_elements; block_elements.reserve(weight); for (int i = 0; i < weight; ++i) { block_elements.push_back(y[current_idx + i]); } // Find the median of the block for the L1 solution. std::nth_element(block_elements.begin(), block_elements.begin() + (weight - 1) / 2, block_elements.end()); long long median = block_elements[(weight - 1) / 2]; // Assign the median to all elements in this block. for (int i = 0; i < weight; ++i) { result[current_idx + i] = median; } current_idx += weight; } return result; } void solve() { int n; long long h; std::cin >> n >> h; std::vector<long long> s(n); for (int i = 0; i < n; ++i) { std::cin >> s[i]; } // --- 1. Upper Bound Problem --- // Transform S -> A such that we need a non-decreasing U'. std::vector<long long> A(n); for (int i = 0; i < n; ++i) { A[i] = s[i] + (long long)i * h; } // Solve for the optimal non-decreasing U'. std::vector<long long> U_prime = compute_isotonic_nondecreasing(A); // Transform back to get the upper bound U on S'. std::vector<long long> U(n); for (int i = 0; i < n; ++i) { U[i] = U_prime[i] - (long long)i * h; } // --- 2. Lower Bound Problem --- // Transform S -> B such that we need a non-increasing L'. std::vector<long long> B(n); for (int i = 0; i < n; ++i) { B[i] = s[i] - (long long)i * h; } // To find non-increasing L', solve for non-decreasing on -B and negate the result. std::vector<long long> minus_B(n); for (int i = 0; i < n; ++i) { minus_B[i] = -B[i]; } std::vector<long long> L_prime_neg = compute_isotonic_nondecreasing(minus_B); // Transform back to get the lower bound L on S'. std::vector<long long> L(n); for (int i = 0; i < n; ++i) { L[i] = -L_prime_neg[i] + (long long)i * h; } // --- 3. Calculate Final Cost --- // The optimal S'[i] is the projection of S[i] onto the interval [L[i], U[i]]. long long total_cost = 0; for (int i = 0; i < n; ++i) { long long s_final_i = s[i]; if (s_final_i < L[i]) { s_final_i = L[i]; } if (s_final_i > U[i]) { s_final_i = U[i]; } total_cost += std::abs(s[i] - s_final_i); } std::cout << total_cost << std::endl; } int main() { setup_io(); solve(); 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...