[USACO15OPEN]被困在haybales(金)
STL
题解:
我们发现假如能突破i+1和j-1的干草包,但是被i和j困住了,那么i和j之前的干草包的大小一定小于这两个干草包。
所以可以用一个set,从大到小依次加入,找到它的前驱和后继,如果跑不出去就给这个区间的每个点都暴力打标记。
打标记之前判断一下左端点有没有标记,这样保证每一段只标记一次。
Code:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <set>
#include <map>
#define D(x) cout<<#x<<"="<<x<<" "
#define E cout<<endl
using namespace std;
const int N = 100005;
struct Haybale{
int w,p;
bool operator < (const Haybale &other) const {
return w > other.w;
}
} d[N];
int n,ans,f[N];
bool cov[N];
map<int,int> dic;
set<int> s;
set<int>::iterator it;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&d[i].w,&d[i].p);
f[i]=d[i].p;
}
sort(f+1,f+1+n);
for(int i=1;i<=n;i++) dic[f[i]]=i;
sort(d+1,d+1+n);
s.insert(d[1].p);
for(int i=2;i<=n;i++){
// D(d[i].p); D(d[i].w); E;
s.insert(d[i].p);
it=s.find(d[i].p);
if(it!=s.begin()){
it--; int l=dic[*it]; int r=dic[d[i].p];
if(d[i].w>=f[r]-f[l] && !cov[l])
for(int j=l;j<r;j++) cov[j]=true;
}
it=s.find(d[i].p); it++;
if(it!=s.end()){
int l=dic[d[i].p]; int r=dic[*it];
if(d[i].w>=f[r]-f[l] && !cov[l])
for(int j=l;j<r;j++) cov[j]=true;
}
}
for(int i=1;i<n;i++) if(cov[i]) ans+=f[i+1]-f[i];
printf("%d\n",ans);
}