专栏文章
题解:P13532 [OOI 2023] Buying gifts / 购买礼物
P13532题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mio0hzar
- 此快照首次捕获于
- 2025/12/02 11:21 3 个月前
- 此快照最后确认于
- 2025/12/02 11:21 3 个月前
我们考虑固定 的最大值,来通过某些数据结构维护 。
把 从小到大排序,遍历。设当前的最大值为 。那比 小的 的选择是可以选 ,也可以选 ,选 对答案无影响, 会影响答案,所以我们要尝试使用 更新答案。比 大的 是必须选择 ,否则与固定 矛盾。
所以对于 需要维护 中的前驱,后继。对于 需要维护 中的最大值。
具体而言,对于 ,我们使用
std::set。找到与 在数轴上最近的 。
对于 。我们可以使用线段树(单点修改,查询全局最大),或者优先队列(每次标记 失效,查询第一个有效的最大值)。时间复杂度 。
CPP#include<bits/stdc++.h>
using namespace std;
constexpr int N = 2e5+10;
int n,a[N],b[N];
struct Node{
int val,ma;
}c[N<<2];
#define mid (l+r)/2
#define ls (u*2)
#define rs (u*2+1)
void pushup(int u) {
c[u].ma = max(c[ls].ma, c[rs].ma);
}
void build(int u,int l,int r) {
if (l == r) {
c[u].val = c[u].ma = b[l];
return ;
}
build(ls,l,mid), build(rs,mid+1,r);
pushup(u);
}
void upd(int u,int l,int r,int x,int v) {
if (l == r) {
c[u].val = c[u].ma = v;
return ;
}
if (x <= mid) upd(ls,l,mid,x,v);
else upd(rs,mid+1,r,x,v);
pushup(u);
}
int mp[N];
void slove() {
cin>>n;
set<int>s;
for (int i=1;i<=n;i++) {
cin>>a[i]>>b[i];
}
build(1,1,n);
iota(mp+1,mp+n+1,1);
sort(mp+1,mp+n+1,[](int x,int y) {
return a[x] < a[y];
});
int mxA = 0, ans = 2e9;
for (int i=1;i<=n;i++) {
mxA = a[mp[i]];
upd(1,1,n,mp[i],0);
auto it = s.lower_bound(mxA);
if (it != s.end()) {
int x = *it;
if (x > c[1].ma) {
ans = min(ans, abs(mxA - x));
}
}
if (it != s.begin()) {
int x = *prev(it);
if (x > c[1].ma) {
ans = min(ans, abs(mxA - x));
}
}
ans = min(ans, abs(mxA - c[1].ma));
s.insert(b[mp[i]]);
}
cout << ans << '\n';
}
int main() {
cin.tie(nullptr) -> sync_with_stdio(false);
int T=1;
while(T--) {
slove();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...