Gym 100851L Landscape Improved(二分+脑洞)
2016-08-16 21:13
281 查看
这题是给你w列方格,然后给你n个方块,让你加进去,使得这个图变得最高,加的要求是,如果这块的下面,以及左下右下都有,才能放
先考虑二分高度,然后知道了最高的高度之后,如何考虑n块能不能放呢
首先要发现,最后的形状,是一个尖的,往两边递减,然后如果碰到一个凸出的,比这个三角形那个地方应有的高度高的话,就会停止下降,所以要在两边找这样的两个位置,并且需要O(n)的维护出来
倒过来考虑,考虑当前位置i,高度是a[i],把他往左边+1延伸,到达高度h的时候,下标是t1,L[t1]=i,右边也是这样,往右边+1延伸,到达高度h的时候下标是t2,R[t2]=i
然后要找到每个下标,最先碰到的这样凸出的柱子
L[i]=max(L[i],L[i−1])
R[i]=min(R[i],R[i+1])
这样你就找到了每个位置,作为最高点的时候,往两边延伸被挡住的位置,然后你只要往中间填方块就行了,看是否小于等于w
代码:
#include <map> #include <set> #include <ctime> #include <stack> #include <queue> #include <cmath> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <sstream> #include <cstdlib> #include <iostream> #include <algorithm> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; #define MAX 100005 #define MAXN 1000005 #define maxnode 205 #define sigma_size 26 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lrt rt<<1 #define rrt rt<<1|1 #define middle int m=(r+l)>>1 #define LL long long #define ull unsigned long long #define mem(x,v) memset(x,v,sizeof(x)) #define lowbit(x) (x&-x) #define pii pair<int,int> #define bits(a) __builtin_popcount(a) #define mk make_pair #define limit 10000 //const int prime = 999983; const int INF = 0x3f3f3f3f; const LL INFF = 0x3f3f; const double pi = acos(-1.0); const double inf = 1e18; const double eps = 1e-4; const LL mod = 772002; const ull mx = 133333331; /*****************************************************/ inline void RI(int &x) { char c; while((c=getchar())<'0' || c>'9'); x=c-'0'; while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; } /*****************************************************/ int a[MAX]; LL sum[MAX]; int L[MAX],R[MAX]; int n; LL w; bool check(int h){ mem(L,0); mem(R,INF); for(int i=1;i<=n;i++){ int t1=i+h-a[i]; int t2=i-(h-a[i]); //cout<<t1<<" "<<t2<<endl; if(t1<=n) L[t1]=max(L[t1],i); if(t2>=1) R[t2]=min(R[t2],i); } for(int i=1;i<=n;i++) L[i]=max(L[i-1],L[i]); for(int i=n;i>0;i--) R[i]=min(R[i],R[i+1]); for(int i=1;i<=n;i++){ if(L[i]==0||R[i]==INF) continue; LL tmp=(1+i-(LL)R[i]+2LL*h)*((LL)R[i]-i)/2; tmp+=((LL)2*h-i+(LL)L[i]+1)*((LL)i-L[i])/2; tmp-=h; tmp-=sum[R[i]-1]-sum[L[i]]; if(tmp<=w) return true; } return false; } int main(){ freopen("landscape.in","r",stdin); freopen("landscape.out","w",stdout); cin>>n>>w; sum[0]=0; int maxn=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); maxn=max(a[i],maxn); sum[i]=sum[i-1]+a[i]; } int l=maxn,r=2e9; while(l<=r){ int mid=(l+r)/2; //cout<<1; if(check(mid)) l=mid+1; else r=mid-1; } cout<<r<<endl; return 0; }
相关文章推荐
- 【二分】NEERC15 L Landscape Improved (Codeforces GYM 100851)
- Codeforces Gym 101608 G WiFi Password(尺取/二分+ST表 )
- Gym - 101257G 24【二分+看题】
- GYM 100488 H.Tony Hawk’s Pro Skater(二分)
- Gym 100971D Laying Cables 二分 || 单调栈
- 【二分】NEERC15 L Landscape Improved(2015-2016 ACM-ICPC)(Codeforces GYM 100851)
- Codeforces Gym - 101234A Hacker Cups and Balls [二分+线段树]
- Gym 100801J Journey to the "The World's Start"(二分+单调队列)
- Yet Another Median Task Gym - 100741G 二分中位数
- Gym - 101194D(二分
- Gym - 101201J Shopping(RMQ+二分)
- Gym 100883J palprime(二分判断点在凸包里)
- Gym 101201J Shopping(RMQ +二分 )
- codeforce Gym 100500F Door Lock (二分)
- 【二分】【半平面交】Gym - 101309J - Jungle Outpost
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
- Gym - 101194D(二分
- Gym - 101308B-二分或者暴力
- [NW Pacific 2016-2017] GYM 101201J Shopping [rmq+二分]
- Gym 100883J palprime(二分判断点在凸包里)