Submission #1257203

#TimeUsernameProblemLanguageResultExecution timeMemory
1257203coin_Pinball (JOI14_pinball)C++20
100 / 100
400 ms55184 KiB
#include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; // A large enough value for infinity const long long inf = 4e15 + 7; const int maxn = 3e5 + 5; struct segment { vector<long long> st; segment() { st.assign(4 * maxn + 5, inf); } void update(int id, int l, int r, int k, long long val) { if (l > r || k < l || k > r) return; if (l == r) { st[id] = min(st[id], val); return; } int mid = l + (r - l) / 2; if (k <= mid) { update(id * 2, l, mid, k, val); } else { update(id * 2 + 1, mid + 1, r, k, val); } st[id] = min(st[id * 2], st[id * 2 + 1]); } long long get(int id, int l, int r, int ul, int ur) { if (l > r || l > ur || r < ul) return inf; if (ul <= l && r <= ur) return st[id]; int mid = l + (r - l) / 2; long long left_min = get(id * 2, l, mid, ul, ur); long long right_min = get(id * 2 + 1, mid + 1, r, ul, ur); return min(left_min, right_min); } }; segment l, r; // l for column 1, r for column N signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int M, N; cin >> M >> N; long long ans = inf; map<int, int> coordsToIdx; set<int> s; vector<tuple<int, int, int, int>> input(M); // Step 1: Coordinate Compression, including boundaries // This is the first critical fix confirmed by the editorial. s.insert(1); s.insert(N); for (int i = 0; i < M; i++) { cin >> get<0>(input[i]) >> get<1>(input[i]) >> get<2>(input[i]) >> get<3>(input[i]); s.insert(get<0>(input[i])); s.insert(get<1>(input[i])); s.insert(get<2>(input[i])); } int cnt = 0; for (int num : s) { coordsToIdx[num] = ++cnt; } int compressed_size = cnt; // Step 2: Initialize DP base cases // The cost to merge column 1 with itself is 0. // The cost to merge column N with itself is 0. l.update(1, 1, compressed_size, coordsToIdx[1], 0); r.update(1, 1, compressed_size, coordsToIdx[N], 0); // Step 3: Process devices and update DP states for (int i = 0; i < M; i++) { int ul = coordsToIdx[get<0>(input[i])]; int ur = coordsToIdx[get<1>(input[i])]; int k = coordsToIdx[get<2>(input[i])]; int val = get<3>(input[i]); // Find the minimum cost to reach this device's *full range* [A_i, B_i] // This is the second critical fix. long long cost_from_left = l.get(1, 1, compressed_size, ul, ur); long long cost_from_right = r.get(1, 1, compressed_size, ul, ur); // Calculate a potential final answer if this device bridges the two paths if (cost_from_left < inf && cost_from_right < inf) { ans = min(ans, cost_from_left + cost_from_right + val); } // Update the DP states: this device creates a new, cheaper way to reach column C_i // Update the left-side (column 1) DP state if (cost_from_left < inf) { l.update(1, 1, compressed_size, k, cost_from_left + val); } // Update the right-side (column N) DP state if (cost_from_right < inf) { r.update(1, 1, compressed_size, k, cost_from_right + val); } } cout << (ans >= inf ? -1 : ans) << 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...