题解 P3127 【[USACO15OPEN]被困在haybales(金)Trappe…】
littleming · · 题解
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;
}