#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |