原题链接

题意

给定一段长度为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. 高可用mongodb集群(分片+副本):性能测试

    目录 ■ 为指定的库和表指定hash分片 ■ 测试模型,即workload模型 ■ 测试指标 ■ workload_s6 ■ 分片集群性能测试数据统计分析 ■ 测试结论 Yahoo! Cloud Se ...

  2. 【Dotnet 工具箱】基于 .NET 6 和 Angular 构建项目任务管理平台

    1.Reha 时间管理大师 Rhea 是一个基于 C# 和 .NET 6 开发的在线任务管理平台,类似于 禅道.Jira.Redmine, 滴答清单等. 支持多视图多维度统一管理任务.多级结构,工作区 ...

  3. c#组合模式详解

    基础介绍:   组合模式用于表示部分-整体的层次结构.适用于希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象的情况.   顾名思义,什么叫部分-整体,比如常见的前端UI,一个 ...

  4. Java Web程序在Tomcat上是如何运行的

    https://blog.csdn.net/fuzhongmin05/article/details/104379514 一个JVM是一个进程,JVM上跑Tomcat,Tomcat上可以部署多个应用. ...

  5. 夯实JAVA基本之一 —— 泛型详解(1):基本使用(转)

    一.引入1.泛型是什么首先告诉大家ArrayList就是泛型.那ArrayList能完成哪些想不到的功能呢?先看看下面这段代码:ArrayList<String> strList = ne ...

  6. [Python急救站]草莓熊的绘制

    草莓熊也是一个热门的图案,今天就用Python绘制一下 import turtle as t # 设置背景颜色,窗口位置以及大小 t.colormode(255) # 颜色模式 t.speed(0) ...

  7. [Python急救站课程]天天向上的力量

    我们要"好好学习,天天向上."那么天天向上的力量到底有多强呢? 1.一年365天,以第1天的能力值为基数,记为1.0,当好好学习时能力值相比前一天提高1‰,当没有学习时由于遗忘等原 ...

  8. 25. 干货系列从零用Rust编写正反向代理,序列化之serde是如何工作的

    wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,内网穿透,后续将实现websocket代理等,会将实现 ...

  9. NEFU OJ Problem1485 贪吃蛇大作战 题解

    Problem:F Time Limit:1000ms Memory Limit:65535K 题目 Description 贪吃蛇大家一定都玩过吧,现在宋哥也要玩这个游戏,最初的时候贪吃蛇从屏幕的左 ...

  10. .NET中有多少种定时器

    .NET中至少有6种定时器,每一种定时器都有它的用途和特点.根据定时器的应用场景,可以分为UI相关的定时器和UI无关的定时器.本文将简单介绍这6种定时器的基本用法和特点. UI定时器 .NET中的UI ...