Luogu1419 区间问题 二分 单调优化
题意
给定一段长度为1e5的序列A,并且给我们一个范围 \([S, T]\), 要求我们求出一段长度在这个范围内的连续子序列,并且要使这个连续子序列的平均值最大,输出这个平均值。
思路
一开始想的是连续子段和相关,于是好久都没有想到正解。
这个题首先可以确定能够使用二分答案的方法,因为“符合条件的最大平均值”是单调的。
之后考虑如何检查序列中符合条件的子序列的平均值是否能达到给定的k。
- 因为我们计算的平均值取自A的一段连续子序列,所以检验成功的表达式为
\]
- 变换可得
\]
看上去我们只需要先求前缀和,然后对每个R,计算 \(max_{1 \le i \le R}A[L...R]\) 然后比较,但是问题在于我们保证了左边最大的同时,右边的(R - L + 1) 却有可能很大而使得可行解不在 \(max_{1 \le i \le R}A[L...R]\) 处取到
所以再变换一次,得
\]
这样我们每次检验时,先把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 区间问题 二分 单调优化的更多相关文章
- [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp
Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...
- 两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 题目大意: 给一棵树,n个节点,每条边有个权值,从每个点i出发有个不经过自己走过的点的最远距离 ...
- 集训第四周(高效算法设计)N题 (二分查找优化题)
原题:poj3061 题意:给你一个数s,再给出一个数组,要求你从中选出m个连续的数,m越小越好,且这m个数之和不小于s 这是一个二分查找优化题,那么区间是什么呢?当然是从1到数组长度了.比如数组长度 ...
- NOIP模拟 最佳序列 - 二分 + 单调队列
题意: 各一个n(\(\le 20000\))的序列,定义纯洁序列为长度len满足\(L \le len \le R\)的序列,纯洁值为某一纯洁序列的平局值,输出所有纯洁序列中最大平均值. 分析: 二 ...
- [USACO12MAR]花盆 二分 单调队列
[USACO12MAR]花盆 二分 单调队列 存在一个长度为\(x\)的区间\([l,r]\),使得区间中最大值与最小值差至少为\(w\),求这个最小的\(x\) \(n\le 100000\),\( ...
- hihoCoder 1389 Sewage Treatment 【二分+网络流+优化】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)
#1389 : Sewage Treatment 时间限制:2000ms 单点时限:2000ms 内存限制:256MB 描述 After years of suffering, people coul ...
- HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...
- AtCoder Regular Contest 070 D - No Need 想法:利用单调性二分+bitset优化
/** 题目:D - No Need 链接:http://arc070.contest.atcoder.jp/tasks/arc070_b 题意:给出N个数,从中选出一个子集,若子集和大于等于K,则这 ...
- CSP 201612-4 压缩编码 【区间DP+四边形不等式优化】
问题描述 试题编号: 201612-4 试题名称: 压缩编码 时间限制: 3.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一段文字,已知单词a1, a2, …, an出现的频率分别t1 ...
- 436. 寻找右区间--LeetCode_二分
来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/find-right-interval 著作权归领扣网络所有.商业转载请联系官方授权,非商业转载请注明出 ...
随机推荐
- 深入理解 Netty FastThreadLocal
作者:vivo 互联网服务器团队- Jiang Zhu 本文以线上诡异问题为切入点,通过对比JDK ThreadLocal和Netty FastThreadLocal实现逻辑以及优缺点,并深入解读源码 ...
- Super Apps 超级应用们背后的道家哲学
众所周知,Elon Musk 想将 Twitter 重新设计定位成一款"超级应用 - X"的野心已经不再是秘密.伴随着应用商店中 Twitter 标志性的蓝鸟 Logo 被 X 取 ...
- python包引用方式总结
本文为博主原创,转载请注明出处: 在Python中,有多种引用包的方式.以下是常见的方式: 1. import语句 import语句是最常见和推荐的引用包的方式.它允许你引入整个包或包中的特定模块/子 ...
- vue之留言板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- sql优化的方法总结
1.对查询进行优化,应该尽量避免全表扫描,首先应考虑在where和order by涉及的列上建立索引 2.应尽量避免在where子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表 ...
- Python 数学函数和 math 模块指南
Python 提供了一组内置的数学函数,包括一个广泛的数学模块,可以让您对数字执行数学任务. 内置数学函数.min() 和 max() 函数可用于在可迭代对象中查找最低或最高值: 示例:查找可迭代对象 ...
- SHA256算法加密工具类
代码如下,请自取 /** * @description: SHA256算法加密 * @author: luolei * @Date: 2022-10-31 17:16 */ public class ...
- 基于AStyle的代码格式化脚本 [已开源]
这是一个简单的windows端脚本 主要用于C/C++代码的格式化 可以添加到鼠标右键,直接在.C/.H文件上右键格式化代码 具体开源地址 https://gitee.com/svchao/code_ ...
- Spring5学习随笔-Spring5的第一个程序(环境搭建、日志框架整合)
第二章.第一个Spring程序 1.软件版本 1.JDK1.8+ 2.Maven3.5+ 3.IDEA2018+ 4.SpringFramework 5.1.4 官网:www.spring.io 2. ...
- [CTF/Web] PHP 反序列化学习笔记
Serialize & unserialize 这两个方法为 PHP 中的方法, 参见 serialize 和 unserialize 的官方文档. 以下内容中可能存在 字段, 属性, 成员 ...