原题链接

题意

给定一段长度为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. IEEE 国际计算科学与工程会议 (CSE-2023)

    随着计算机系统变得越来越庞大和复杂,基于数据的计算技术在支持下一代科学和工程应用方面发挥着关键作用.如今,科学和工程中基于云的复杂大数据应用由异构软件/硬件/网络组件组成,这些组件的容量.可用性和环境 ...

  2. SonarQube系列-通过配置扫描分析范围,聚焦关键问题

    在许多情况下,你可能不希望分析项目中每个源文件的各个方面.例如,项目可能包含生成的代码.库中的源代码或有意复制的代码.在这种情况下,跳过这些文件分析的部分或全部方面是有意义的,从而消除干扰并将焦点缩小 ...

  3. Opencv系列之一:简介与基本使用

    1 Opencv简介 Opencv是计算机视觉中经典的专用库,其支持多语言,跨平台,功能强大.Opencv-Python为Opencv提供了Python接口,使得使用者在Python中能够调用C/C+ ...

  4. CSP 2022 游寄

    Day -2147483648 官网有了通知,但选手注册不知为何坏掉了: 先开坑: Day -大概两个月 注册了,但老师还没给我审核呜呜呜 第一轮 早上 早上起床就直接来机房了,不用跑操欸嘿. 上午 ...

  5. 前后端都用得上的 Nginx 日常使用经验

    前言 nginx 是一个高性能的开源反向代理服务器和 web 服务器,一般用来搭建静态资源服务器.负载均衡器.反向代理,本文将分享其在 Windows/docker 中的使用,使用 nssm 部署成服 ...

  6. Python利用pandas进行数据合并

    当使用Python中的pandas库时,merge函数是用于合并(或连接)两个数据框(DataFrame)的重要工具.它类似于SQL中的JOIN操作,允许你根据一个或多个键(key)将两个数据框连接起 ...

  7. Dash应用浏览器端回调常用方法总结

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/dash-master 大家好我是费老师,回调函数是我们在Dash应用中实现各种交互功能的核心,在绝大 ...

  8. Postgresql——jsonb类型

    Postgresql Json 最近有个功能,需要用到 NoSQL 数据库.但是又不想因为这个小小的功能给系统增加一个 MongoDB 数据库,于是就想到了 Postgresql 支持 JSON 类型 ...

  9. 音色逼真、韵律自然的AI人声克隆限时福利!

    声音,为数字人注入灵魂. 2023云栖大会上,阿里云视频云接受了CCTV-2财经频道的采访,分享并演示了如何利用云端智能剪辑,一站式完成数字人渲染及视频精编二创. 正如视频开头所呈现的AI重现演员&q ...

  10. VUE同级组件之前方法调用

    实现:Index.vue页面调用nav.vue页面里的getLeftMenu()方法 一.首先先建一个公共文件,命名eventBus.js,内空为: import Vue from 'vue'expo ...