分析

题目要求求一个最大的实数\(x\),使得某长度在\([S,T]\)之间的区间\([L,R]\)满足

\[\frac{\sum_{i=L}^{R}a_i}{R-L+1}=x
\]

\[\sum_{i=L}^{R}a_i=x*(R-L+1)
\]

由于答案满足单调性,所以可以二分\(x\),转化为判断问题,即判断

\[\sum_{i=L}^{R}a_i\geq x*(R-L+1)
\]

\(\rightarrow\)

\[\sum_{i=L}^{R}\left(a_i-x \right)\geq0
\]

对这个式子求前缀和,就可快速算出一段区间的和,令

\[sum_i=\sum_{i=1}^{i}\left(a_i-x \right)
\]

则区间\([L,R]\)合法的条件为

\[sum_R-sum_{L-1}\geq0
\]

转化成这种形式,已经很好做了。维护一个单增的单调队列,然后判断当前遍历元素是否大于等于队首元素即可。

时间复杂度

假设数据范围为\(A\),则二分答案是\(O(\log A)\)的,判断一次用了前缀和和单调队列,是\(O(n)\)的,总时间复杂度为\(O(n\log A)\)。

小优化

题目要求保留3位小数,而对浮点数的操作很麻烦,所以不妨对每个数乘10000(多一位是因为要四舍五入),然后算答案时再除10000.0就行了。


用STL的deque实现单调队列,嫌慢手打,使用相同API即可~~(然而这题不卡可以水^_^)~~。

#include<iostream>
#include<cstdio>
#include<deque>
#include<cstring>
#define rg register
template<typename T>inline T read(T&x)
{
T data=0;
int w=1;
char ch=getchar();
while(ch!='-'&&!isdigit(ch))
ch=getchar();
if(ch=='-')
w=-1,ch=getchar();
while(isdigit(ch))
data=data*10+ch-'0',ch=getchar();
return x=data*w;
}
using namespace std;
typedef long long ll; const int MAXN=1e5+7;
int n,S,T;
int a[MAXN];
ll sum[MAXN]; // prefix sum
int L=1e8,R=-1e8; deque <int> Q; inline bool judge(int x)
{
// cerr<<"judging x="<<x<<endl;
memset(sum,0,sizeof(sum));
for(rg int i=1;i<=n;++i)
{
sum[i]=sum[i-1]+a[i]-x;
// clog<<"sum["<<i<<"]= "<<sum[i]<<endl;
}
Q.clear();
for(rg int i=S,p=0;i<=n;++i,++p)
{ // 只有一段不包括本身的区间内合法,就开两个扫描线
while(!Q.empty()&&sum[Q.back()]>sum[p])
Q.pop_back();
Q.push_back(p);
while(Q.front()<i-T) // 这里不用判空是因为p一定存在
Q.pop_front();
if(sum[i]-sum[Q.front()]>=0)
return 1;
}
// cerr<<"failed"<<endl;
return 0;
} int main()
{
read(n);read(S);read(T);
for(rg int i=1;i<=n;++i)
{
read(a[i]);
a[i]*=1e4;
// cerr<<"a["<<i<<"]= "<<a[i]<<endl;
L=min(L,a[i]);
R=max(R,a[i]);
}
while(L<R)
{
int M=(L+R+1)>>1;
if(judge(M))
L=M;
else
R=M-1;
}
printf("%.3f",L/1e4);
}

Hint

最后说一下单调队列的边界问题。合法区间\([L,R]\)满足

\[S\leq R-L+1\leq T
\]

由于使用前缀和,那么\(i\),\(p\)应满足

\[S+1\leq i-p+1\leq T+1
\]

也就是说应弹掉\(p<i-T\)的那些点。

还有就是二分答案的边界。求最后一个类型应该int M=(L+R+1)>>1;

LG1419 【寻找段落】的更多相关文章

  1. LuoguP1419 寻找段落(二分 单调队列

    题目描述 给定一个长度为n的序列a_i,定义a[i]为第i个元素的价值.现在需要找出序列中最有价值的“段落”.段落的定义是长度在[S,T]之间的连续序列.最有价值段落是指平均值最大的段落, 段落的平均 ...

  2. P1419 寻找段落

    题目描述 给定一个长度为n的序列a_i,定义a[i]为第i个元素的价值.现在需要找出序列中最有价值的“段落”.段落的定义是长度在[S,T]之间的连续序列.最有价值段落是指平均值最大的段落, 段落的平均 ...

  3. 洛谷—— P1419 寻找段落

    https://www.luogu.org/problem/show?pid=1419 题目描述 给定一个长度为n的序列a_i,定义a[i]为第i个元素的价值.现在需要找出序列中最有价值的“段落”.段 ...

  4. [洛谷P1419] 寻找段落

    一道单调队列的好题 传送门:>Here< 题意:求一个连续子段,其长度在\([S,T]\)之间,使其平均值最大.保留三位小数 解题思路 考虑二分答案,转化为判定问题.设当前二分到\(k\) ...

  5. 【洛谷 P1419】 寻找段落(二分答案,单调队列)

    题目链接 开始还以为是尺取.发现行不通. 一看标签二分答案,恍然大悟. 二分一个\(mid\)(实数),把数列里每个数减去\(mid\),然后求前缀和,在用单调队列维护\(sum[i-t\text{~ ...

  6. 【Luogu】P1419寻找段落(单调队列)

    题目链接 不知为何状态突然奇差无比,按说这题本来应该是水题的,但不仅不会做,还比着题解爆零五次 二分平均值(想到了),单调队列维护最大区间和(想到了但是不会,???为什么我不会???) #includ ...

  7. luoguP1419 寻找段落(二分答案+单调队列)

    题意 给定一个长度为n的序列a1~an,从中选取一段长度在s到t之间的连续一段使其平均值最大.(n<=100000) 题解 二分答案平均值. judge时把每一个a[i]-mid得到b[i] 在 ...

  8. 洛谷P1419寻找段落

    题目 单调队列+前缀和 #include <bits/stdc++.h> #define N 101001 using namespace std; int n, s, t; int da ...

  9. luogu1419 寻找段落 (二分,单调队列)

    单调队列存坐标 #include <iostream> #include <cstdio> #include <cstring> #include <algo ...

随机推荐

  1. Java下载https文件上传到阿里云oss服务器

    Java下载https文件上传到阿里云oss服务器 今天做了一个从Https链接中下载音频并且上传到OSS服务器,记录一下希望大家也少走弯路. 一共两个类: 1 .实现自己的证书信任管理器类 /** ...

  2. 使用 Python 的 Socket 模块构建一个 UDP 扫描工具

    译文:oschina 英文:bt3gl 当涉及到对一些目标网络的侦察时,出发点无疑是首先发现宿主主机.这个任务还可能包含嗅探和解析网络中数据包的能力. 几周前,我曾经谈到了如何使用Wireshark来 ...

  3. TitanX服务器登陆网关

  4. 51nod-1534-博弈

    1534 棋子游戏  题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 波雷卡普和瓦西里喜欢简单的逻辑游戏.今天他们 ...

  5. 从客户端(......)中检测到有潜在危险的 Request.Form 值

    在提交表单时候,asp.net 提示:"从客户端(......)中检测到有潜在危险的 Request.Form 值" .asp.net中的请求验证特性提供了某一等级的保护措施防止X ...

  6. kaptcha验证码使用

    参数配置: Constant 描述 默认值 kaptcha.border 图片边框,合法值:yes , no yes kaptcha.border.color 边框颜色,合法值: r,g,b (and ...

  7. java并发带返回结果的批量任务执行(CompletionService:Executor + BlockingQueue)

    转载:http://www.it165.net/pro/html/201405/14551.html 一般情况下,我们使用Runnable作为基本的任务表示形式,但是Runnable是一种有很大局限的 ...

  8. 第n次考试

    题目: 1.堆方块  [题目描述] 给定N个方块,排成一行,将它们编号1到N. 再给出P个操作: M i j表示将i所在的那一堆移到j所在那一堆的顶上. C i表示一个询问,询问i下面有多少个方块. ...

  9. oracle_sql语句的大全

    # 建立数据库struts   CREATE DATABASE IF NOT EXISTS struts DEFAULT CHARACTER SET GBK; 1.登录:(管理员)conn sys/p ...

  10. Java——线程定时器

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...