1 条题解
-
0
自动搬运
来自洛谷,原作者为

littleming
**搬运于
2025-08-24 21:45:34,当前版本为作者最后更新于2017-06-03 15:34:43,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
https://li-mi.github.io/2017/06/03/Usaco2015-Open-Gold-Trapped-in-the-Haybales/
题目好绕啊。。
大概就是求Bessie站在哪里逃不出去。。
当然可以暴力。。100000,显然只能用O(nlogn),官方的标程也是用这个复杂度的。
假如Bessie从一个很低的区间一直往外冲,结果撞在了很高的一个区间的干草堆上。如果从低区间往高区间求解,不是很亏吗。。于是从高区间向低区间求解↓
先把干草堆的高度排递减序,将每个高度值插入set,在set里面二分找它左右相邻的干草堆,
如果这个区间正好能把Bessie拦住,就把这个区间内的干草堆标记一下,以后就不用再标记了。
这里采用左闭右开,将左边的干草堆标记,右边的不标记。
还有一点,数据达到1e9,要离散化。(lz用map)
时间复杂度就是O(nlogn),但由于用了map常数会大跑得慢。。
#include<bits/stdc++.h> using namespace std; typedef long long LL; inline int read() { int x=0;char ch=getchar(); while(ch<'0'||ch>'9'){ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } int n,pos[100008],l,r,ans; struct node{ int s,p; }a[100008]; map<int,int> m; set<int> s; set<int>::iterator si; bool vis[100008]; inline bool cmp(const int a,const int b){return a<b;} inline bool cmp2(const node a,const node b){return a.s>b.s;} int main() { n=read(); for(int i=1;i<=n;i++){ a[i].s=read();a[i].p=read(); pos[i]=a[i].p; } sort(pos+1,pos+n+1,cmp); for(int i=1;i<=n;i++) m[pos[i]]=i; sort(a+1,a+n+1,cmp2); s.insert(a[1].p); for(int i=2;i<=n;i++){ if(*s.begin()<a[i].p){ si=--s.upper_bound(a[i].p); l=m[*si];r=m[a[i].p]; if(pos[r]-pos[l]<=a[i].s&&!vis[l]){ for(int j=l;j<r;j++) vis[j]=1; } } if(*--s.end()>a[i].p){ si=s.upper_bound(a[i].p); l=m[a[i].p];r=m[*si]; if(pos[r]-pos[l]<=a[i].s&&!vis[l]){ for(int j=l;j<r;j++) vis[j]=1; } } s.insert(a[i].p); } for(int i=1;i<n;i++){ if(vis[i]) ans+=pos[i+1]-pos[i]; } cout<<ans; return 0; }
- 1
信息
- ID
- 2191
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者