题解引用

引理1: 区间 \([l,r]\) 是最优解的必要不充分条件是: \(l,r\) 分别是区间的最小值与最大值.

这很显然,若假设不成立,当区间向内缩小时,一定有分子不变,分母变小,进而算出更优解,与假设矛盾.

引理2: 最优解不小于 \(x\) 的充要条件为存在区间 \([i,j]\),使得 \((A_{i}-i\times x)-(A_{j}-j\times x )-k\times x\ge 0\) 或 \((A_{i}+i\times x)-(A_{j}+j\times x )-k\times x\ge 0\) .

证明一下引理2:

题设转化为公式表达为:

\[\exist i,j\to\frac{M(i,j)-m(i,j)}{j-i+k}\ge x
\]

移项:

\[\exist i,j\to M(i,j)-m(i,j) \ge j\times x-i\times x+k \times x
\]
\[\exist i,j\to M(i,j)-m(i,j)-j\times x+i\times x \ge k \times x
\]

假设我们已经通过引理1,使区间可能成为最优解,那么公式可以变为:

\[\exist i,j\to \begin{cases}A_{i}-A_{j}-j\times x+i\times x \ge k \times x\ (A_{i} \ge A_{j})\\ A_{j}-A_{i}-j\times x+i\times x \ge k \times x\ (A_{i} \le A_{j})\end{cases}
\]

略微整理一下即为上述引理内容.

题目分析

根据题解可以看出来,我们一共有两个引理需要维护.

注意到引理1我们可以通过以下方式使用单调队列快速维护:

  • 遍历不是以端点为阶段,而是以长度为阶段. 即当 \(A_{i} \le A_{j}\) 时,固定左端点,使其始终为单调队列最小值,伸长右端点,不断更新最值,这样即可一次遍历找出所有符合引理1的区间. 另一种情况同理.

注意到题中 \(ans \le 1000\) ,利用引理2,我们可以使用二分答案来枚举最终的答案. 所以我们来梳理一下这道题的总流程:

  1. 二分枚举一个答案值 \(x\).
  2. 根据引理2,我们分别维护 \(A_{i}+i\times x\) 与 \(A_{i}-i\times x\) 的单调的队列,方便进行值 \(x\) 的可行性判断.
  3. 根据引理1,我们通过上述方法找出全部可能为最优解的区间.
  4. 根据引理2,只要有一个区间满足条件,那么值 \(x\) 即为可行的.
  5. 重复上述步骤。直到精度满足要求.

代码实现

double a[5000001],c[5000001];
int main(){
int t;
cin>>t;
while(t--){
int n,k,L,R;
cin>>n>>k>>L>>R;
for(int i=1;i<=n;++i){
cin>>a[i];
}
double l=0,r=1000;
while(r-l>1e-7){ //1e-7比较玄学,开小了容易超时,开大了达不到精度,还会莫名tle
double mid=(l+r)/2; //使用循环版本的二分答案
bool flag=false;
deque<int> q;
for(int i=1;i<=n;++i){ //check部分开始
c[i]=a[i]-1.0*mid*i; //维护a[i]-x*i
}
for(int i=L;i<=n;++i){ //枚举区间长度
while(!q.empty()&&i-q.front()>=R){
q.pop_front();
} //维护最值
while(!q.empty()&&c[q.back()]>=c[i-L+1]){
q.pop_back();
}
q.push_back(i-L+1);
if(c[i]-c[q.front()]>=mid*k){
l=mid;
flag=true; //假如有一个满足的,check成功
break;
}
}
if(!flag){ //再写一遍另一种情况
q.clear();
for(int i=1;i<=n;++i){
c[i]=a[i]+1.0*mid*i; //维护a[i]+x*i
}
for(int i=L;i<=n;++i){
while(!q.empty()&&i-q.front()>=R){
q.pop_front();
}
while(!q.empty()&&c[q.back()]<=c[i-L+1]){
q.pop_back();
}
q.push_back(i-L+1);
if(c[q.front()]-c[i]>=mid*k){
l=mid;
flag=true;
break;//check部分结束
}
}
if(!flag){
r=mid;//二分结束
}
}
}
double ans=l; //根据答案算答案,写的比较不好,就当个参考
deque<int> q1,q2;
for(int i=1;i<=L-1;++i){
while(!q1.empty()&&a[q1.back()]<=a[i]){
q1.pop_back();
}
while(!q2.empty()&&a[q2.back()]>=a[i]){
q2.pop_back();
}
q1.push_back(i);
q2.push_back(i);
}
for(int i=L;i<=n;++i){
while(!q1.empty()&&a[q1.back()]<=a[i]){
q1.pop_back();
}
while(!q2.empty()&&a[q2.back()]>=a[i]){
q2.pop_back();
}
q1.push_back(i);
q2.push_back(i);
while(!q1.empty()&&i-q1.front()>=L){
q1.pop_front();
}
while(!q2.empty()&&i-q2.front()>=L){
q2.pop_front();
}
if(!q1.empty()&&!q2.empty()){
ans=max(ans,1.0*(a[q1.front()]-a[q2.front()])/(L+k-1));
}
}
printf("%.4f\n",ans);
}
}

[TK] 送礼物的更多相关文章

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

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

  2. CH2401 送礼物(双向dfs)

    CH2401 送礼物 描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了.某神牛有N个礼物,且异常沉重,但是GY的力气也异常的大(-_- ...

  3. P1340 送礼物

    时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了. ...

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

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

  5. [TYVJ2340] 送礼物 - 双向搜索

    题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Local 题目描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到 ...

  6. JSOI 2015 送礼物

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

  7. [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) ...

  8. TYVJ1340 送礼物

    P1340 送礼物 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后 ...

  9. 「CH2401」送礼物 解题报告

    CH2401 送礼物 描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了.某神牛有N个礼物,且异常沉重,但是GY的力气也异常的大(-_- ...

  10. 「JSOI2015」送礼物

    「JSOI2015」送礼物 传送门 看到这题首先想到分数规划. 我们发现对于当前区间,如果它的最大值和最小值不是分居区间的两个端点的话,那么我们显然可以把两端多出去的部分舍掉,因为,在区间最大值最小值 ...

随机推荐

  1. AT_abc246_d 题解

    洛谷链接&Atcoder 链接 本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读. 题目简述 给定整数 \(N\),请你找到最小的整数 \(X\),满足: \(X \ge N\). ...

  2. vscode取消json文件注释下划线

    使用 vscode 打开一个json文件,如果有单行或多行注释,则会显示红色下划线,解决办法如下: 方法1 点击底部的JSON,选择 JSON with Comments 即可,然后红色下划线消失,底 ...

  3. C# 泛型SQLHelper<T>类

    示例[1] 1.创建SQLHelper类 using System.Collections.Generic; using System.Configuration; using System.Data ...

  4. 在.NET Web API设置响应输出Json数据格式常用的两种方式

    前言 在ASP.NET Core Web API中设置响应输出Json数据格式常用以下两种方式:可以通过添加System.Text.Json或Newtonsoft.JsonJSON序列化和反序列化库在 ...

  5. android 点击退出按钮 结束所有的activity 回到手机主页面

    android 点击退出按钮 结束所有的activity 回到手机主页面我 实现了回到主页面 但是在点击这个程序 他还是回到**退出的界面 ** 我要实现点击按钮回到手机主页面 在点击这个程序后就重新 ...

  6. 低代码如何借助 K8s 实现高并发支持?

    引言 在当今这个数字化时代,互联网的普及和技术的飞速发展使得应用程序面临着前所未有的挑战,其中最为显著的就是高并发访问的需求.随着用户数量的激增和业务规模的扩大,如何确保应用在高并发场景下依然能够稳定 ...

  7. 【MybatisPlus】 Field '主键' doesn't have a default value

    使用MybatisPlus的 PoMapper执行Insert插入方法报错: 复原场景: 1.PO对象存在主键值(双主键) 2.表中数据为空 3.首次插入 这张表使用的是双主键,发现原因是因为PO设置 ...

  8. CentOS下离线安装gcc环境,图文详细,方法全面

    CentOS下离线安装gcc环境,图文详细,方法全面 下载 方式1:如果有网的虚拟机还没有安装,可以直接 yum install --downloadonly --downloaddir=/root/ ...

  9. 删除个文件夹,vfs2上传文件到ftp就异常553,这么不经事吗

    开心一刻 今天逛街碰到街头采访,一上来就问我敏感话题 主持人:小哥哥,你单身吗 我:是啊 主持人:你找女朋友的话,是想找一个小奶猫呢,还是小野猫呢 我沉思了一下,叹气道:如果可以的话,我想找个人,而且 ...

  10. Jenkins配置分布式构建环境——添加固定Agent并使用JNLP启动Agent详解

    1.概述 在<Jenkins部署架构概述>这篇博文中对Jenkins部署架构进行了讲解.对于分布式架构,Jenkins包括固态Agent和动态Agent两种方案. 固定Agent(常用于虚 ...