C. Hacker, pack your bags!
题目链接👈
题目描述🥰

题目思路😀
我们首先需要处理的是如何找出持续时间和为x的两个代金券的问题
而解决这个问题最好的数据结构就是哈希表,我们可以用哈希表存入持续时间是k的所有代金券,当我们需要知道持续时间为x-k的代金券是否存在的话,那就用哈希表的count函数即可
其次我们需要解决的问题是,对于一个代金券而言,我们如何从符合和为x且与之不重叠的代金券里面找到价值最小的呢?
如果我们一个一个枚举过去,那么时间复杂度会达到O(n^2),很显然不符合我们题目的要求
而如何去优化这个问题呢?
答案是可以使用前后缀最小值并配合二分来优化
我们可以先预处理每一个时长为e的前缀最小费用和后缀最小费用,这样在后续查询单一个代金券e的时候,我们就可以用二分找到x-e的代金券里面符合x-e.r<l的最小费用和x-e.l>r的最小费用,时间就优化到nlogn的时间复杂度
AC代码🧠
struct edge{
int l;
int r;
int val;
};
void solve() {
int n, x;
cin >> n >> x;
map<int, vector<edge>> hash;
for (int i = 0; i < n; ++i) {
int l, r, val;
cin >> l >> r >> val;
int d = r - l + 1;
hash[d].push_back({l, r, val});
}
map<int, vector<pair<int,int>>> premin, sufmin;
for (auto &[d, vec] : hash) {
// 预处理premin:按r升序,记录前缀最小费用
sort(vec.begin(), vec.end(), [](const edge &a, const edge &b) {
return a.r < b.r;
});
vector<pair<int, int>> tmp;
int min_cost = LLONG_MAX;
for (auto &v : vec) {
min_cost = min(min_cost, v.val);
tmp.emplace_back(v.r, min_cost);
}
premin[d] = tmp;
// 预处理sufmin:按l升序,记录后缀最小费用
tmp.clear();
min_cost = LLONG_MAX;
for (int i = vec.size() - 1; i >= 0; --i){
min_cost = min(min_cost, vec[i].val);
tmp.emplace_back(vec[i].l, min_cost);
}
reverse(tmp.begin(), tmp.end());
sufmin[d] = tmp;
}
int ans = LLONG_MAX;
for (auto &[d1, vec] : hash) {
int d2 = x - d1;
if (d2 <= 0 || !hash.count(d2)) continue;
for (auto &v : vec) {
int l = v.l, r = v.r;
// 查找d2中满足 r_j < l 的最小费用(premin按r升序)
auto &pre = premin[d2];
if (!pre.empty()) {
/*
如果用的是(l - 1, 0LL)
当存在 r_j == l - 1 且其费用 >= 0 的代金券时,
这些代金券的 pair(r_j, cost) 可能等于或大于 (l - 1, 0)
此时 upper_bound 的返回位置可能提前,导致漏掉部分满足 r_j <= l - 1 的代金券。
*/
auto it = upper_bound(pre.begin(), pre.end(), (PII){l - 1, LLONG_MAX});
if (it != pre.begin()) {
--it;
ans = min(ans, v.val + it->second);
}
}
// 查找d2中满足 l_j > r 的最小费用(sufmin按l升序)
auto &suf = sufmin[d2];
if (!suf.empty()){
auto it = lower_bound(suf.begin(), suf.end(), (PII){r + 1, 0LL});
if (it != suf.end()) {
ans = min(ans, v.val + it->second);
}
}
}
}
cout << (ans != LLONG_MAX ? ans : -1) << endl;
}
posted on
浙公网安备 33010602011771号