题意

题目链接

分析

  • 分数规划之后可以得到式子:\(max-min-r*mid+l*mid\geq k*mid\) .

  • 贪心选择,肯定区间的端点是极小或者极大值。特殊处理区间长度 \(\leq L\) 的情况。

  • 有两种情况分别对应 \(r\) 作为最大和最小值。

    • \(r\) 作为最大值:枚举 \(a_r-r*mid\),查询 \(min\{a_l-l*mid\}\)并减去.
    • \(r\) 作为最小值:枚举 \(a_l+l*mid\),查询 \(min\{a_r+r*mid\}\)并减去.
  • 单调队列优化优化查询,因为如果一个点不是最后答案的话这个值一定比最优解大.

  • 总时间复杂度为\(O(nlogn)\)。

代码

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
#define re(x) memset(x,0,sizeof x)
typedef long long LL;
inline int gi(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=5e4 + 7;
const double eps=1e-7;
int T,n,k,L,R,tl,hd;
int q[N],a[N],f[2][N][18];
void rmq_init(){
rep(i,1,n) f[0][i][0]=f[1][i][0]=a[i];
for(int k=1;1<<k<=n;++k)
for(int i=1;1<<k<=n-i+1;++i)
f[0][i][k]=min(f[0][i][k-1],f[0][i+(1<<k-1)][k-1]),
f[1][i][k]=max(f[1][i][k-1],f[1][i+(1<<k-1)][k-1]);
}
int query(int l,int r,int g){
int k=0;
for(;1<<k+1<=r-l+1;k++);
if(!g) return min(f[g][l][k],f[g][r-(1<<k)+1][k]);
return max(f[g][l][k],f[g][r-(1<<k)+1][k]);
}
bool check(double mid){
double ans=-1.0*(1e14);
for(int i=L;i<=n;++i) if(1.0*(query(i-L+1,i,1)-query(i-L+1,i,0))/(L-1+k)>=mid) return 1;
hd=1,tl=0;
rep(i,1,n-L+1){
for(;hd<=tl&&i-q[hd]>R-L;++hd);
for(;hd<=tl&&(a[q[tl]]-q[tl]*mid)>=(a[i]-i*mid);--tl);
q[++tl]=i;
Max(ans,(a[i+L-1]-(i+L-1)*mid)-(a[q[hd]]-q[hd]*mid));
}
hd=1,tl=0;
for(int i=n;i>=L;--i){
for(;hd<=tl&&q[hd]-i>R-L;++hd);
for(;hd<=tl&&(a[q[tl]]+q[tl]*mid)>=(a[i]+i*mid);--tl);
q[++tl]=i;
Max(ans,(a[i-L+1]+(i-L+1)*mid)-(a[q[hd]]+q[hd]*mid));
}
return ans>=k*mid;
}
void work(){
n=gi(),k=gi(),L=gi(),R=gi();
rep(i,1,n) a[i]=gi();a[n+1]=0;
rmq_init();
double l=0,r=1000;
while(r-l>eps){
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
printf("%.4lf\n",l);
}
int main(){
T=gi();
while(T--) work();
return 0;
}

[BZOJ4476][JSOI2015]送礼物[分数规划+单调队列]的更多相关文章

  1. 【BZOJ4476】[Jsoi2015]送礼物 分数规划+RMQ

    [BZOJ4476][Jsoi2015]送礼物 Description JYY和CX的结婚纪念日即将到来,JYY来到萌萌开的礼品店选购纪念礼物.萌萌的礼品店很神奇,所有出售的礼物都按照特定的顺序都排成 ...

  2. BZOJ_4476_[Jsoi2015]送礼物_01分数规划+单调队列

    BZOJ_4476_[Jsoi2015]送礼物_01分数规划+单调队列 Description JYY和CX的结婚纪念日即将到来,JYY来到萌萌开的礼品店选购纪念礼物. 萌萌的礼品店很神奇,所有出售的 ...

  3. P6087 [JSOI2015]送礼物 01分数规划+单调队列+ST表

    P6087 [JSOI2015]送礼物 01分数规划+单调队列+ST表 题目背景 \(JYY\) 和 \(CX\) 的结婚纪念日即将到来,\(JYY\) 来到萌萌开的礼品店选购纪念礼物. 萌萌的礼品店 ...

  4. [BZOJ4476] [JSOI2015] 送礼物 (01分数规划+ST表)

    [BZOJ4476] [JSOI2015] 送礼物 (01分数规划+ST表) 题面 给出n,k,l,r和序列a,要求从a中选一段连续的区间[i,j]出来,使得M(i,j)-m(i,j)/(j-i+k) ...

  5. BZOJ4476 JSOI2015送礼物(分数规划+单调队列)

    看到这个式子当然先二分答案.得max-min-(j-i+k)ans>=0. 显然max-min相同的情况下所选区间长度越短越好,所以max和min都应该取在边界.那么实际上我们根本不用管端点是否 ...

  6. BZOJ 5281--[Usaco2018 Open]Talent Show(分数规划&单调队列&DP)

    5281: [Usaco2018 Open]Talent Show Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 79  Solved: 58[Sub ...

  7. bzoj4476 [Jsoi2015]送礼物

    化简式子 $M>=m+ans*(r-l+k)$ 发现$M,m$确定时,总区间长度越小越好,于是假定右端点为最小值$M+ans*l>=m+ans*r+ans*k$, 右面都确定了,但最大值仍 ...

  8. 【BZOJ3316】JC loves Mkk 分数规划+单调队列

    [BZOJ3316]JC loves Mkk Description Input 第1行,包含三个整数.n,L,R.第2行n个数,代表a[1..n]. Output 仅1行,表示询问答案.如果答案是整 ...

  9. 【BZOJ 3316】JC loves Mkk 01分数规划+单调队列

    单调栈不断吞入数据维护最值,数据具有单调性但不保证位置为其排名,同时可以按照进入顺序找出临近较值单调队列队列两端均可删除数据但只有队末可以加入数据,仍然不断吞入数据但同时可以额外刨除一些不符合条件的数 ...

随机推荐

  1. phpcas 整合 ecms的问题

    如果有ecms整合phpCAS经验的小伙伴可以给我留言,有偿付费 需求是:ecms登录自动跳转到CAS认证(已完成),认证后直接跳转到帝国cms系统中,并保持帝国cms系统权限等都和以前一样 正常使用 ...

  2. Opengl---gluLookAt函数详解(转)

    转自 http://www.cnblogs.com/jiangu66/archive/2013/04/06/3003122.html 下面的一段摘自百度百科: 视点转换 函数原型 void gluLo ...

  3. zabbix日常监控项nginx(五)

    1.开启nginx监控 2.编写脚本来进行数据采集 3.设置用户自定义参数 4.重启zabbix-agent 5.添加item.创建图形.创建触发器 6.创建模板 注:第一次使用可以按需求制定好模板, ...

  4. 【教程】【FLEX】#004 反射机制

    总结: 目前用到反射的主要有两个方法 1.  getDefinitionByName    //根据类名,返回对象(反射实例化对象) 2.  describeType                 ...

  5. Notepad++调用python

    ***首先确保在cmd下能直接运行python*** (博主的环境:win10 下2和3共存) 接下来进入主题,用Notepad++打开py文件,然后按 F5 键弹出运行窗口,输入以下内容: pyth ...

  6. Nodejs Redis 全部操作方法

    安装  npm install redis --save demo var redis = require('redis'); var client = redis.createClient('637 ...

  7. 【node.js】Stream(流)

    Stream 有四种流类型: Readable - 可读操作. Writable - 可写操作. Duplex - 可读可写操作. Transform - 操作被写入数据,然后读出结果. 所有的 St ...

  8. npm发布插件步骤

    开发好一个插件后,要想让其他人也能使用该插件需要将插件发布到npm上,具体步骤如下: 1.添加npm用户: npm adduser Username: your name Password: your ...

  9. Kafka设计解析(十八)Kafka与Flink集成

    转载自 huxihx,原文链接 Kafka与Flink集成 Apache Flink是新一代的分布式流式数据处理框架,它统一的处理引擎既可以处理批数据(batch data)也可以处理流式数据(str ...

  10. ZCMU 1019: 分金币

    解题思路: 附上刘汝佳老师的解题过程: 首先最终每个人的金币数量可以计算出来,它等于金币总数除以人数n.接下来用M来表示每个人最终拥有的金币数. 现在假设编号为 i 的人初始有Ai 枚金币,对于1号来 ...