bzoj4476[JSOI2015]送礼物
2017-03-07 16:59
148 查看
选择一段区间之后,对答案有影响的只是区间中的最大最小值,因此考虑枚举最大值找最优的最小值.(不需要保证这两个数值是对应的区间内的实际最大最小值,实际最大最小值对答案产生的贡献一定也会另外被枚举到).
由对称性,只考虑最小值在最大值左边的情况.对于下标等于x的数,如果让下标在[x-l+1,x-1]内的数字作为对应的最小值,那么必然需要延伸这个区间使得区间长度达到l.那么对于这种情况,我们查询这个下标范围内的最小数值即可(每个数值对应的区间长度相同).如果让下标和x的差值大于l小于r的数字作为最小值,则不同的数值对应不同的区间长度,且贪心可得对应的区间一定是一端为最大值,一段为最小值.分数规划,二分答案+单调队列判定即可.二分精度要高一点才不会WA….
由对称性,只考虑最小值在最大值左边的情况.对于下标等于x的数,如果让下标在[x-l+1,x-1]内的数字作为对应的最小值,那么必然需要延伸这个区间使得区间长度达到l.那么对于这种情况,我们查询这个下标范围内的最小数值即可(每个数值对应的区间长度相同).如果让下标和x的差值大于l小于r的数字作为最小值,则不同的数值对应不同的区间长度,且贪心可得对应的区间一定是一端为最大值,一段为最小值.分数规划,二分答案+单调队列判定即可.二分精度要高一点才不会WA….
#include<cstdio> #include<algorithm> using namespace std; const int maxn=50005; int a[maxn],st[maxn][20]; int buf[maxn]; int n,k,l,r; int rmq(int l,int r){ if(l>n||r<1)return 0x7f7f7f7f; if(l<1)l=1; if(r>n)r=n; int j=buf[r-l+1]; return min(st[l][j],st[r-(1<<j)+1][j]); } int q[maxn]; bool check(double ans){ int head=0,tail=0; for(int i=1;i<=n-l;++i){ while(head!=tail&&i+l>q[head]+r-1)head++; while(head!=tail&&(a[q[tail-1]]-q[tail-1]*ans)>(a[i]-i*ans))tail--; q[tail++]=i; if(a[i+l]-(i+l+k)*ans>a[q[head]]-q[head]*ans)return true; } head=0;tail=0; for(int i=n;i>l;--i){ while(head!=tail&&i-l<q[head]-r+1)head++; while(head!=tail&&(a[q[tail-1]]+(q[tail-1]+k)*ans>a[i]+(i+k)*ans))tail--; q[tail++]=i; if(a[i-l]+(i-l)*ans>a[q[head]]+(q[head]+k)*ans)return true; } return false; } int main(){ int tests;scanf("%d",&tests); for(int j=0;(1<<j)<maxn;++j)buf[1<<j]=j; for(int i=3;i<maxn;++i){ if(!buf[i])buf[i]=buf[i-1]; } while(tests--){ scanf("%d%d%d%d",&n,&k,&l,&r); for(int i=1;i<=n;++i)scanf("%d",&a[i]); for(int i=1;i<=n;++i)st[i][0]=a[i]; for(int j=1;(1<<j)<=n;++j){ for(int i=1;i<=n;++i){ st[i][j]=st[i][j-1]; if(i+(1<<j-1)<=n&&st[i+(1<<j-1)][j-1]<st[i][j])st[i][j]=st[i+(1<<j-1)][j-1]; } } double ans=0; for(int i=1;i<=n;++i){ ans=max(ans,(a[i]-min(rmq(i+1,i+l-1),rmq(i-l+1,i-1)))/double(l-1+k)); } double l=0,r=1e4; while(r-l>1e-7){ double mid=(l+r)/2.0; if(check(mid))l=mid; else r=mid; } printf("%.4f\n",max(ans,l)); } return 0; }
相关文章推荐
- BZOJ4476 JSOI2015送礼物(分数规划+单调队列)
- bzoj4476 [Jsoi2015]送礼物
- bzoj4476: [Jsoi2015]送礼物 分数规划
- bzoj 4476: [Jsoi2015]送礼物 二分答案+单调队列
- 【BZOJ4476】[Jsoi2015]送礼物 分数规划+RMQ
- [BZOJ]4476: [Jsoi2015]送礼物 分数规划+RMQ
- 【BZOJ4476&JSOI2015】送礼物(二分,RMQ)
- BZOJ_4476_[Jsoi2015]送礼物_01分数规划+单调队列
- bzoj 4472: [Jsoi2015]salesman
- BZOJ4476 送礼物
- 4484: [Jsoi2015]最小表示
- bzoj 4474: [Jsoi2015]isomorphism
- 【JSOI2015】【JZOJ 4063】非诚勿扰
- 【bzoj4487】[Jsoi2015]染色问题 容斥原理
- Bzoj4488 [Jsoi2015]最大公约数
- BZOJ 4484: [Jsoi2015]最小表示 拓扑排序 bitset
- 4488: [Jsoi2015]最大公约数
- BZOJ4477 JSOI2015字符串树(可持久化trie)