【BZOJ4101】[Usaco2015 Open]Trapped in the Haybales Silver 二分
【BZOJ4101】[Usaco2015 Open]Trapped in the Haybales (Silver)
Description
Farmer John has received a shipment of N large hay bales (1≤N≤100,000), and placed them at various locations along the road
connecting the barn with his house. Each bale j has a size Sj and a distinct position Pj giving its location along the one-dimensional
road. Bessie the cow is currently located at position B, where there is no hay bale.
Bessie the cow can move around freely along the road, even up to the position at which a bale is located, but she cannot cross
through this position. As an exception, if she runs in the same direction for D units of distance, she builds up enough speed to
break through and permanently eliminate any hay bale of size strictly less than D. Of course, after doing this, she might open up
more space to allow her to make a run at other hay bales, eliminating them as well.
FJ is currently re-painting his house and his barn, and wants to make sure Bessie cannot reach either one (cows and fresh paint
do not make a good combination!) Accordingly, FJ wants to make sure Bessie never breaks through the leftmost or rightmost hay
bale, so she stays effectively trapped within the hay bales. FJ has the ability to add hay to a single bale of his choosing to help
keep Bessie trapped. Please help him determine the minimum amount of extra size he needs to add to some bale to ensure Bessie
stays trapped.
农夫约翰将N(1<=N<=100000)堆干草放在了一条平直的公路上。第j堆干草的大小为Sj,坐标为Pj。奶牛贝茜位于一个没有干草堆的点B。
奶牛贝茜可以在路上自由移动,甚至可以走到某个干草堆上,但是不能穿过去。但是如果她朝同一个方向跑了D个单位的距离,那么她就有足够大的速度去击碎任何大小严格小于D的干草堆。当然,在这之后如果她继续朝着该方向前进,那么她的速度不会清零。
约翰可以指定某堆干草,并增大它的大小,他想知道他最少需要增大多少,才能把奶牛贝茜困住,或者根本不可能。
Input
The first line of input contains N as well as Bessie's initial position B. Each of the next N lines describes a bale, and
contains two integers giving its size and position. All sizes and positions are in the range 1…109.
Output
Print a single integer, giving the minimum amount of hay FJ needs to add to prevent Bessie from escaping.
Print -1 if it is impossible to prevent Bessie's escape.
Sample Input
5 7
8 1
1 4
3 8
12 15
20 20
8 1
1 4
3 8
12 15
20 20
Sample Output
4
题解:当我又一次看到了这道熟悉的题,想起了几年前狂WA不止的恐惧,我屏住呼吸,再一次点开了这道题目,就在这时,我突然震惊的发现——
我TM看错题了!!!
好吧,这题说的是只能增大一个干草堆的大小,我以前一直认为是多个(也就是两个),并且还真的写出来了一种算法,拍极限数据都没问题!!
进入正题:
先讨论增大Bessie左边的干草堆的情况,我们枚举右边的干草堆j,设增大的大小为k,加高的干草堆编号为i,干草堆大小size,干草堆坐标x,容易列出方程
也就是size[i]+x[i]越大越好,前提x[i]不能太小
于是我们先处理一下size[i]+x[i]的最大值,然后二分x[i],然后更新答案就行了
增大Bessie右边的干草堆的情况也类似
#include <cstdio> #include <cstring> #include <iostream> #include <set> #include <algorithm> using namespace std; const int maxn=100010; int n,m,ans; struct bale { int x,d; }s[maxn]; int f[maxn]; set<int> s1,s2; bool cmp(bale a,bale b) { return a.x<b.x; } int main() { scanf("%d%d",&n,&m); ans=1<<30; int i,j,l,r,mid; for(i=1;i<=n;i++) scanf("%d%d",&s[i].d,&s[i].x); s[++n].x=m; sort(s+1,s+n+1,cmp); for(i=1;i<=n;i++) if(s[i].x==m) { m=i; break; } f[m]=-1<<30; for(i=m-1;i>=1;i--) f[i]=max(f[i+1],s[i].x+s[i].d); for(i=m+1;i<=n;i++) f[i]=max(f[i-1],s[i].d-s[i].x); for(i=m+1;i<=n;i++) { l=1,r=m; while(l<r) { mid=l+r>>1; if(s[i].x-s[mid].x<=s[i].d) r=mid; else l=mid+1; } if(r<m) ans=min(ans,max(0,s[i].x-f[r])); } for(i=1;i<m;i++) { l=m+1,r=n+1; while(l<r) { mid=l+r>>1; if(s[mid].x-s[i].x<=s[i].d) l=mid+1; else r=mid; } if(l>m+1) ans=min(ans,max(0,-s[i].x-f[l-1])); } if(ans==1<<30) printf("-1"); else printf("%d",ans); return 0; }
| 欢迎来原网站坐坐! >原文链接<