「JSOI2015」送礼物

传送门

看到这题首先想到分数规划。

我们发现对于当前区间,如果它的最大值和最小值不是分居区间的两个端点的话,那么我们显然可以把两端多出去的部分舍掉,因为,在区间最大值最小值都不变的情况下,区间肯定是越短越优的。

但是要注意一点就是区间长度也是有下界的。

所以说我们就先处理所有区间长度为下界 \(L\) 的情况,然后再对区间长度位于 \([L + 1, R]\) 的区间做处理。

二分答案 \(mid\) ,假设当前区间是 \([l, r]\) 那么就有:

\[\frac{\max_{i = l}^r\{a_i\} - \min_{i = l}^r\{a_i\}}{r - l + k} \ge mid \\\Rightarrow (\max_{i = l}^r\{a_i\} + l \times mid) - (\min_{i = l}^r\{a_i\} + r \times mid) \ge k \times mid
\]

由于我们之前说过最大值和最小值一定分居区间的两个端点(是这里不妨假设 \(a_l\) 为最大值,另一种情况同理

那么就有:

\[(a_l + l \times mid) - (a_r + r \times mid) \ge k \times mid
\]

所以我们可以令 \(f_i = a_i + i \times mid\) ,然后枚举左端点,查询右端点的最小值即可(这个可以用 \(\text{ST}\) 表维护)

但是要记得判断右端点越界的情况。

参考代码:

#include <algorithm>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
} const int _ = 5e4 + 5;
const double eps = 1e-7; int n, k, L, R, a[_], lg[_];
int mn[18][_], mx[18][_]; double f[18][_]; inline int query_mn(int l, int r) {
int x = lg[r - l + 1];
return min(mn[x][l], mn[x][r - (1 << x) + 1]);
} inline int query_mx(int l, int r) {
int x = lg[r - l + 1];
return max(mx[x][l], mx[x][r - (1 << x) + 1]);
} inline double query(int l, int r) {
int x = lg[r - l + 1];
return min(f[x][l], f[x][r - (1 << x) + 1]);
} inline bool chk(double mid) {
for (rg int i = 1; i <= n; ++i) f[0][i] = a[i] + mid * i;
for (rg int i = 1; i <= lg[n]; ++i)
for (rg int j = 1; j + (1 << i) - 1 <= n; ++j)
f[i][j] = min(f[i - 1][j], f[i - 1][j + (1 << (i - 1))]);
double res = -2e9;
for (rg int i = 1; i + L <= n; ++i)
res = max(res, f[0][i] - query(i + L, min(i + R - 1, n)));
return res >= k * mid;
} inline bool check(double mid) {
if (chk(mid)) return 1;
reverse(a + 1, a + n + 1);
if (chk(mid)) return 1;
return 0;
} inline void solve() {
read(n), read(k), read(L), read(R);
for (rg int i = 2; i <= n; ++i) lg[i] = lg[i >> 1] + 1;
for (rg int i = 1; i <= n; ++i) read(a[i]), mn[0][i] = mx[0][i] = a[i];
for (rg int i = 1; i <= lg[n]; ++i)
for (rg int j = 1; j + (1 << i) - 1 <= n; ++j) {
mn[i][j] = min(mn[i - 1][j], mn[i - 1][j + (1 << (i - 1))]);
mx[i][j] = max(mx[i - 1][j], mx[i - 1][j + (1 << (i - 1))]);
}
double ans = -2e9;
for (rg int i = 1; i + L - 1 <= n; ++i)
ans = max(ans, 1.0 * (query_mx(i, i + L - 1) - query_mn(i, i + L - 1)) / (L + k - 1));
double l = 0, r = 1000;
while (r - l > eps) {
double mid = (l + r) / 2;
if (check(mid)) l = mid; else r = mid;
}
printf("%.4lf\n", max(ans, l));
} int main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
int T; read(T);
while (T--) solve();
return 0;
}

「JSOI2015」送礼物的更多相关文章

  1. 「CH2401」送礼物 解题报告

    CH2401 送礼物 描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了.某神牛有N个礼物,且异常沉重,但是GY的力气也异常的大(-_- ...

  2. 「JSOI2015」串分割

    「JSOI2015」串分割 传送门 首先我们会有一个贪心的想法:分得越均匀越好,因为长的绝对比短的大. 那么对于最均匀的情况,也就是 \(k | n\) 的情况,我们肯定是通过枚举第一次分割的位置,然 ...

  3. 「JSOI2015」isomorphism

    「JSOI2015」isomorphism 传送门 我们还是考虑树哈希来判同构. 但是我们需要使用一些特殊的手段来特殊对待假节点. 由于是无向树,我们首先求出重心,然后以重心为根跑树哈希. 此处我们不 ...

  4. 「JSOI2015」symmetry

    「JSOI2015」symmetry 传送门 我们先考虑构造出原正方形经过 \(4\) 种轴对称变换以及 \(2\) 种旋转变换之后的正方形都构造出来,然后对所得的 \(7\) 个正方形都跑一遍二维哈 ...

  5. 「JSOI2015」地铁线路

    「JSOI2015」地铁线路 传送门 第一问很简单:对于每条线路建一个点,然后所有该条线路覆盖的点向它连边,权值为 \(1\) ,然后它向所有线路上的点连边,权值为 \(0\) . 然后,跑一边最短路 ...

  6. 「JSOI2015」染色问题

    「JSOI2015」染色问题 传送门 虽然不是第一反应,不过还是想到了要容斥. 题意转化:需要求满足 \(N + M + C\) 个条件的方案数. 然后我们就枚举三个数 \(i, j, k\) ,表示 ...

  7. 「JSOI2015」圈地

    「JSOI2015」圈地 传送门 显然是最小割. 首先对于所有房子,权值 \(> 0\) 的连边 \(s \to i\) ,权值 \(< 0\) 的连边 \(i \to t\) ,然后对于 ...

  8. 「JSOI2015」最小表示

    「JSOI2015」最小表示 传送门 很显然的一个结论:一条边 \(u \to v\) 能够被删去,当且仅当至少存在一条其它的路径从 \(u\) 通向 \(v\) . 所以我们就建出正反两张图,对每个 ...

  9. 「JSOI2015」套娃

    「JSOI2015」套娃 传送门 考虑贪心. 首先我们假设所有的套娃都互相不套. 然后我们考虑合并两个套娃 \(i\),\(j\) 假设我们把 \(i\) 套到 \(j\) 里面去,那么就可以减少 \ ...

随机推荐

  1. thinkphp中简单的控制器使用

    1.在路由(route.php)中定义一条路由 Route::rule('new/:name/:id','index/News/read'); 2.在index下的controller控制器中新建一个 ...

  2. vue插槽的使用

    一.插槽的基本使用 二.具名插槽的使用 三.编译作用域的例子 四.作用域插槽 一.插槽的基本使用     1.插槽的基本使用<slot></slot>     2.插槽的默认值 ...

  3. codeforces Codeforces Round #597 (Div. 2) Constanze's Machine 斐波拉契数列的应用

    #include<bits/stdc++.h> using namespace std; ]; ]; ; int main() { dp[] = ; scanf(); ); ; i< ...

  4. day14 tar

    04. 系统中如何对文件进行压缩处理 压缩的命令 tar 压缩命令语法: tar zcvf /oldboy/oldboy.tar.gz 指定要压缩的数据文件 z 压缩的方式 为zip c 创建压缩包文 ...

  5. wamp 安装

    下载地址:http://www.wampserver.com/ 安装 完成安装 安装目录下打开 安装成功

  6. 通过FormData对象可以组装一组用 [XMLHttpRequest]发送请求的键/值对,它可以更灵活方便的发送表单数据。

    工作记录用 1 大概页面,点击选择按钮,选择文件,填写备注并可以上传前预览,然后点击上传按钮开始上传 2 html+js代码 <h2>Test</h2> <div id= ...

  7. Linux - Shell - #!/bin/bash

    概述 简单解释一下 shell 脚本卡头的 #!/bin/bash 水一篇, 少一篇 背景 shell 脚本中的注释 通常是 以# 卡头的行 但是有时候执行 shell 的时候, 会有这种内容 #!/ ...

  8. 牛客多校第一场 A Equivalent Prefixes 单调栈(笛卡尔树)

    Equivalent Prefixes 单调栈(笛卡尔树) 题意: 给出两个数组u,v,每个数组都有n个不同的元素,RMQ(u,l,r)表示u数组中[l,r]区间里面的最小值标号是多少,求一个最大的m ...

  9. MySQL8.0服务启动(windows10)

    mysql下载地址:https://dev.mysql.com/downloads/mysql/ 根目录下配置文件:my.ini [mysqld]# 设置3306端口port=3306# 设置mysq ...

  10. MySql 怎么存取 Emoji

    01.前言 Emoji 在我们生活中真的是越来越常见了,几乎每次发消息的时候不带个 Emoji,总觉得少了点什么,似乎干巴巴的文字已经无法承载我们丰富的感情了.对于我们开发者来说,如何将 Emoji ...