首页 > 其他分享 >最佳序列 题解

最佳序列 题解

时间:2024-10-23 09:01:06浏览次数:5  
标签:le 题解 ll mid 最佳 maxn 序列 diff

最佳序列 题解

题目描述

你得到了一个 \(N\) 个非负整数组成的序列 \(A\)。

我们称由序列 \(A\) 的连续若干项组成的新序列为 \(A\) 的一个连续子序列。给出两个正整数 \(L,R(L \le R)\)。称 \(A\) 的每一个长度不小于 \(L\) 且不大于 \(R\) 的连续子序列为一个纯洁序列,定义纯洁度为纯洁序列的所有元素的平均值。

请你求出所有纯洁序列中的纯洁度的最大值。

输入格式

输入文件的第一行包括 \(3\) 个正整数 \(N,L,R\)。

第二行包括 \(N\) 个数,按顺序依次表示序列 \(A\) 的每一项。

输出格式

输出文件包括一行,一个实数,保留 \(4\) 位小数,表示答案。

样例

样例输入

3 2 3
6 2 8

样例输出

5.3333

数据范围与提示

对 \(10\%\) 的数据满足,\(1 \le N \le 200\)。

对 \(20\%\) 的数据满足,\(1 \le N \le 2000\)。

对 \(50\%\) 的数据满足,\(1 \le N \le 20000\)。

对 \(100\%\) 的数据满足,\(1 \le N \le 10^5, 1 \le L \le R \le N, 0 \le A_i \le 10^6\)。

分析

前缀和,然后暴力枚举所有合法区间的方法很容易想到,可以得 \(55\) 分。(要开 long long

\(100\) 分做法:既然有最大值,说明如果平均超过最大值的区间是不存在的,而小于最大值的区间肯定存在,可以想到二分答案。

如何判断答案合法性呢?我们令 \(mid\) 为当前枚举的平均数,\(diff[i] = arr[i] - mid\),那么只要存在长度在 \(L\) 到 \(R\) 之间的区间 \(diff[i]\) 总和大于等于 \(0\),就说明是合法的;反之,若不存在,则说明当前的 \(mid\) 过大。

由于我们只需要找到任意一个 \(diff[i]\) 总和大于等于 \(0\) 的区间,我们可以用单调队列来维护,单调递增,然后找到一个合法区间即可。

代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll maxn = 1e5 + 5;
ll n, L, R;
ll arr[maxn];

double diff[maxn], pre[maxn];
int que[maxn];
inline bool check(double mid) {
	for (int i = 1; i <= n; i++) {
		diff[i] = arr[i] - mid; // 求与当前二分的平均值的差
		pre[i] = pre[i - 1] + diff[i]; // 前缀和
	}
	int head = 1, tail = 0;
	double ans = -1e9;
	for (int i = L; i <= n; i++) { // 序列长度最短为 L,所以序列的末端从 L 开始
		while (head <= tail && pre[que[tail]] >= pre[i - L]) tail--;
		que[++tail] = i - L; // 维护单调递增的队列,队首的前缀和最小
		while (head <= tail && que[head] < i - R) head++; // 令区间长度超过 R 的出队
		if (head <= tail) ans = max(ans, pre[i] - pre[que[head]]); // 队首最小,这里 pre[i] - pre[que[head]] 就最大,我们只要找到一个 >= 0 的即可。
		if (ans >= 0.0) return true;
	}
	return false;
}

int main() {
	freopen("bestseq.in", "r", stdin);
	freopen("bestseq.out", "w", stdout);
	scanf("%lld%lld%lld", &n, &L, &R);
	for (int i = 1; i <= n; i++) {
		scanf("%lld", &arr[i]);
	}
	double l = 0, r = 1e8; // 实数二分
	while (r - l > 1e-7) {
		double mid = (l + r) / 2.0;
		if (check(mid)) l = mid;
		else r = mid;
	}
	printf("%.4lf", l);
	return 0;
}

标签:le,题解,ll,mid,最佳,maxn,序列,diff
From: https://www.cnblogs.com/jxyanglinus/p/18494363

相关文章

  • 题解 [NOIP2022] 建造军营
    树形\(dp\)好题。观察题目发现,如果B国袭击后,导致A国两个军营不联通,那么B国袭击的一定是一条割边,反之,如果袭击的不是割边,那么不会导致任何影响。所以先进行边双缩点,变成一棵树,记每个联通块(缩完后)内的点数为\(wa\),边数为\(wb\),不妨先考虑对于树的情况如何处理。将问题进行转......
  • 20241022 校测T1 链链链(chain)题解
    Problem链链链chain你有一个长度为\(n\)的链,编号为\(i(1≤i<n)\)的边连接着结点\(i\)与\(i+1\)。每个结点\(i\)上有一个整数\(a_i\)。你需要做以下操作\(n−1\)次:•选择一条还未被断开的边,设其连接了点\(i\)与\(i+1\),将其断开。•断边后,对于所......
  • 洛谷 P2572 [SCOI2010] 序列操作 做题记录
    其实和小白逛公园差不多,编写代码的难度远大于思路难度,难点是调试:注意在区间异或\(1\)的时候分清代码里的最长连续\(1\)的长度和\(1\)的个数。注意查询最长\(1\)的时候要用结构体上传,如果用到了定值len的话要赋值。注意如果只用一个tag的话,遇到区间异或要对原先......
  • 多特征变量序列预测(二)——CNN-LSTM-Attention风速预测模型
    往期精彩内容:时序预测:LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较全是干货|数据集、学习资料、建模资源分享!EMD、EEMD、FEEMD、CEEMD、CEEMDAN的区别、原理和Python实现(一)EMD-CSDN博客EMD、EEMD、FEEMD、CEEMD、CEEMDAN的区别、原理和Python实现(二)EEMDEMD、EE......
  • 时间序列分析
    以下是使用Python进行时间序列分析的十个示例代码,这些代码涵盖了不同的时间序列分析方法,包括ARIMA、季节性分解、指数平滑等。1.自回归(AR)模型fromstatsmodels.tsa.ar_modelimportAutoRegimportnumpyasnp#生成示例数据data=np.random.randn(100).cumsum()#拟合A......
  • P9751 [CSP-J 2023] 旅游巴士 题解
    思路首先,举一个例子,假如说小Z到了入口,但是没到时间,所以没法进去,该怎么办?当然是等$k$个时间单位呀.除此之外,像到了其他景区,但是还没开门怎么办?继续等$k$的非负整数倍时间呀.知道这个后,我们先定义状态$f_{i,j}$,表示到达点$i$时,路径长度(即时间)$mod$$k$的最早时......
  • P9749 [CSP-J 2023] 公路 题解
    此题贪心食用更佳在输入油价的时候,我们边计算油价的最小值和路程和.当路程之和$>0$时,计算油价并且减去对应路程即可.注意事项要开$long$$long$!!!.代码#include<iostream>#include<cstdio>#include<cmath>#include<cstring>usingnamespacestd;typedeflonglo......
  • P9750 [CSP-J 2023] 一元二次方程 题解
    大模拟此题大模拟即可,只需注意几点:分母$>0$.要给根式化简.分数要约分.求较大根,那就$b^2$加$\bigtriangleup$即可.分母>0因为求根公式中,分母中只有$a$一个未知数,所以我们只需保证$a>0$即可.所以,当$a<0$时,我们把$a,b,c$全部取相反值.但这也是......
  • 题解:P10949 四叶草魔杖
    2024/10/16更新:修改了状态的枚举方式,时间复杂度变为\(O(3^n)\)。题目传送门前言本篇题解默认您已熟练掌握最小生成树、状压dp及其应用,如果您还不会,请先阅读相关博客。分析我们要选出一条边,通过边转移能量,使得所有宝石的能量都为\(0\)。这看上去挺麻烦的,让我们挖掘一......
  • 题解:AT_joisc2019_k 合併 (Mergers)
    题目传送门前言联考题,被初一的我切了。看到题解区里没有Tarjan做法,于是来补一篇Tarjan题解。分析因为相同州的城市不会分裂,所以可以给相同州的成市连边(注意不是两两连边,连成一个环就行),发现把国家分成两个部分就相当于断掉一条道路。那么如果整个国家就是一个边双连通分量,......