原题链接

题意

给定一段长度为1e5的序列A,并且给我们一个范围 \([S, T]\), 要求我们求出一段长度在这个范围内的连续子序列,并且要使这个连续子序列的平均值最大,输出这个平均值。

思路

一开始想的是连续子段和相关,于是好久都没有想到正解。

  • 这个题首先可以确定能够使用二分答案的方法,因为“符合条件的最大平均值”是单调的。

  • 之后考虑如何检查序列中符合条件的子序列的平均值是否能达到给定的k。

    • 因为我们计算的平均值取自A的一段连续子序列,所以检验成功的表达式为
\[A[L...R] / (R - L + 1) \ge k
\]
  • 变换可得
\[A[L...R] \ge k * (R - L + 1)
\]
  • 看上去我们只需要先求前缀和,然后对每个R,计算 \(max_{1 \le i \le R}A[L...R]\) 然后比较,但是问题在于我们保证了左边最大的同时,右边的(R - L + 1) 却有可能很大而使得可行解不在 \(max_{1 \le i \le R}A[L...R]\) 处取到

  • 所以再变换一次,得

\[A[L...R] - k * (R - L + 1) \ge 0
\]
  • 这样我们每次检验时,先把A全部元素-k得到A‘数组,(前缀和数组也同时更新),然后对每个R,计算 \(max_{1 \le i \le R}A’[L...R]\) ,此时的最大值就是 \(max_{1 \le i \le R}[A[L...R] - k * (R - L + 1)]\), 然后与0比较,就可以正确寻找可行解。

  • 求最值的过程,由于子区间长度范围为\([S, T]\),所以我们求最值的范围事实上是 $ max_{R - t \le i \le R - s}{sum_R - sum_i} $,也就是需要求长度为 \(t - s + 1\) 的区间上的 \(sum_i\) 的最小值,固定区间长度的最值问题,使用单调队列。

  • 之后就是二分了,注意精度就可以

AC代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const double ff = 1e-4; double su[100005];
int n, s, t, m; struct ab
{
int l;
double v;
} que[100005]; bool chk(double k)
{
for (int i = 1; i <= n; ++i)
{
su[i] -= i * k;
}
su[0] = 0; bool fl = false;
int hd = 1, tl = 1;
for (int i = 0; i < m; ++i)
{
while (tl > hd && que[tl - 1].v >= su[i])
{
--tl;
}
que[tl].l = i;
que[tl++].v = su[i];
if (su[i + s] - que[hd].v >= 0)
{
fl = true;
break;
}
} if (!fl)
{
for (int i = m; i <= n - s; ++i)
{
while (hd < tl && que[hd].l + m <= i)
{
++hd;
}
while (tl > hd && que[tl - 1].v >= su[i])
{
--tl;
}
que[tl].l = i;
que[tl++].v = su[i];
if (su[i + s] - que[hd].v >= 0)
{
fl = true;
break;
}
}
} for (int i = 1; i <= n; ++i)
{
su[i] += i * k;
}
return fl;
} int main()
{
scanf("%d", &n);
scanf("%d%d", &s, &t);
m = t - s + 1;
su[0] = 0;
double ll = 0, rr = 0;
for (int i = 1; i <= n; ++i)
{
double xx;
scanf("%lf", &xx);
su[i] = su[i - 1] + xx;
ll = min(ll, xx);
rr = max(rr, xx);
}
while (ll + ff * 5 <= rr)
{
double mid = (ll + rr) / 2;
if (chk(mid))
{
ll = mid;
}
else
{
rr = mid;
}
}
while (chk(ll))
{
ll += ff;
}
printf("%.3f", ll - ff);
return 0;
}

Luogu1419 区间问题 二分 单调优化的更多相关文章

  1. [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp

    Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...

  2. 两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 题目大意: 给一棵树,n个节点,每条边有个权值,从每个点i出发有个不经过自己走过的点的最远距离 ...

  3. 集训第四周(高效算法设计)N题 (二分查找优化题)

    原题:poj3061 题意:给你一个数s,再给出一个数组,要求你从中选出m个连续的数,m越小越好,且这m个数之和不小于s 这是一个二分查找优化题,那么区间是什么呢?当然是从1到数组长度了.比如数组长度 ...

  4. NOIP模拟 最佳序列 - 二分 + 单调队列

    题意: 各一个n(\(\le 20000\))的序列,定义纯洁序列为长度len满足\(L \le len \le R\)的序列,纯洁值为某一纯洁序列的平局值,输出所有纯洁序列中最大平均值. 分析: 二 ...

  5. [USACO12MAR]花盆 二分 单调队列

    [USACO12MAR]花盆 二分 单调队列 存在一个长度为\(x\)的区间\([l,r]\),使得区间中最大值与最小值差至少为\(w\),求这个最小的\(x\) \(n\le 100000\),\( ...

  6. hihoCoder 1389 Sewage Treatment 【二分+网络流+优化】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)

    #1389 : Sewage Treatment 时间限制:2000ms 单点时限:2000ms 内存限制:256MB 描述 After years of suffering, people coul ...

  7. HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化

    HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...

  8. AtCoder Regular Contest 070 D - No Need 想法:利用单调性二分+bitset优化

    /** 题目:D - No Need 链接:http://arc070.contest.atcoder.jp/tasks/arc070_b 题意:给出N个数,从中选出一个子集,若子集和大于等于K,则这 ...

  9. CSP 201612-4 压缩编码 【区间DP+四边形不等式优化】

    问题描述 试题编号: 201612-4 试题名称: 压缩编码 时间限制: 3.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一段文字,已知单词a1, a2, …, an出现的频率分别t1 ...

  10. 436. 寻找右区间--LeetCode_二分

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/find-right-interval 著作权归领扣网络所有.商业转载请联系官方授权,非商业转载请注明出 ...

随机推荐

  1. Android 通过solid来定义不同边框的颜色,可以只定义一个边框的颜色

    以下是设置按钮的右边框和底边框颜色为红色,边框大小为3dp,如下图: 在drawable新建一个 btnstyle.xml的文件,内容如下: <?xml version="1.0&qu ...

  2. http 500 错误

    214 [Thu Sep 09 16:03:54.919334 2021] [:error] [pid 32045] [client 124.238.184.230:23796] script '/v ...

  3. sqlserver在设计表结构时,如何选择字段的数据类型

    在设计表结构时,选择适当的字段数据类型是非常重要的,它会直接影响数据库的性能.存储空间和数据的完整性.以下是在 SQL Server 中选择字段数据类型时的一些建议和理由: 1. 整数类型:在 SQL ...

  4. Windows 95 的辉煌诞生历史

    1992 年 2 月,Windows 3.1 的研发即将结束,而 Windows 团队正忙得不亦乐乎地计划他们的下一盘大棋.到了 3 月 5 日,他们终于悠哉悠哉地敲定了战略大计:横扫桌面.笔记本.移 ...

  5. 虹科干货 | 虹科Redis企业版数据库的延迟如此之小,proxy功不可没!

    在Redis企业版集群的后台发生了许多事件,proxy(代理)隐藏了数据库客户端的所有活动. 大多数开发人员在构建应用程序时都会从小规模开始,使用简单的Redis开源(Redis OSS)数据库.在初 ...

  6. nodejs修改npm包安装位置

    适用于非个人电脑.便携使用 npm config set cache D:\nodejs\node_cache npm config set prefix D:\nodejs npm config s ...

  7. camerabin error:"Internal data stream error,使用QT打开MIPI摄像头

    使用QT自带的QCamera打开MIPI摄像头 遇到:camerabin error:"Internal data stream error 降低分辨率为640*480 TRANSLATE ...

  8. QGradient渐变填充

    QGradient渐变填充 QGradient (一)简介 (二)枚举类型 1.spread 2.CoordinateMode 3.type (三)常用函数 1.coordinateMode() 2. ...

  9. JUC并发编程学习笔记(十六)Volatile

    Volatile 保证可见性 private volatile static Integer num = 0; 使用了volatile关键字,即可保证它本身可被其他线程的工作内存感知,即变化时也会被同 ...

  10. 新手VSCode配置C++20

    最近买了本C++20的书,想要自己配置下在VScode的环境 例子代码: #include <iostream> #include <format> int main() { ...