【ST】【CF855B】 Marvolo Gaunt's Ring
Description
给定三个数 \(p~,~q~,~r~\),以及一个数组 \(a\),
找出三个数 \(i~,~j~,~k\) ,其中 \(i~\leq~j~\leq~k\) 最大化 \(p~\times~a_i~+~q~\times~a_j~+~r~\times~a_r\)
Input
第一行是数组长度 \(n\) 以及 \(p~,~q~,~r~\)。
第二行 \(n\) 个数代表这个数组
Output
输出一个整数代表答案
Hint
\(-10^5~\leq~n~\leq~10^5\)
其他数据 \(\in~[-10^9~,~10^9]\)
Solution
考虑最暴力的方法,枚举 \(i~,~j~,~k\) ,计算答案,时间复杂度\(O(n^3)\)
然后考虑如果枚举了其中两个值,剩下一个可以直接通过查询区间最值确定。例如,如果枚举了 \(i~,~j\),则 \(k\) 对应的最优解一定是 ( \(k~>~0\) 时) \(k~\times~\max_{s~=~j}^{n}~a_s\),( \(k~\leq~0\) 时) \(k~\times~\min_{s~=~j}^{n}~a_s\)。枚举其它两个元素同理。这样就可以用ST预处理区间最值,然后做到 \(O(1)\) 查询,复杂度 \(O(n\log n)-O(n^2)\) 。
考虑上述做法的缺陷在于枚举量还是太大,能否可以只枚举一个位置呢?我们发现如果枚举一个位置以后可以确定剩下两个区间,就可以只枚举一个位置。于是发现枚举 \(j\) 符合要求。于是只枚举 \(j\) 按照上面的方法求 \(i~,~k\) 的对应答案。时间复杂度 \(O(n\log n)~-~O(n)\)
Code
#include <cmath>
#include <cstdio>
#include <algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif
#define rg register
#define ci const int
#define cl const long long
typedef long long int ll;
namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
}
template <typename T>
inline void qr(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
}
template <typename T>
inline void ReadDb(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
if (ch == '.') {
ch = IPT::GetChar();
double base = 1;
while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
}
if (lst == '-') x = -x;
}
namespace OPT {
char buf[120];
}
template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
rg int top=0;
do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
}
const int maxn = 100010;
const ll INF = -1000000000ll;
int n;
int LOG[maxn];
ll p, q, r, ans = -3000000000000000010ll;
ll MU[maxn], ST[2][20][maxn];
ll ask(ci, ci, ci);
int main() {
freopen("1.in", "r", stdin);
qr(n); qr(p); qr(q); qr(r);
for (rg int i = 1; i <= n; ++i) qr(MU[i]);
for (rg int i = 0; (1 << i) <= n; ++i) {
LOG[1 << i] = i;
}
for (rg int i = 3; i <= n; ++i) if(!LOG[i]) LOG[i] = LOG[i - 1];
for (rg int i = 0; i < 20; ++i)
for (rg int j = 0; j < maxn; ++j)
ST[1][i][j] = INF;
for (rg int i = 0; i < 20; ++i)
for (rg int j = 0; j < maxn; ++j)
ST[0][i][j] = -INF;
for (rg int i = 1; i <= n; ++i) ST[1][0][i] = ST[0][0][i] = MU[i];
for (rg int i = 1; i < 20; ++i) {
int len = (1 << i) - 1;
for (rg int l = 1; l <= n; ++l) {
int r = l + len; if (r > n) break;
ST[0][i][l] = std::max(ST[0][i - 1][l], ST[0][i - 1][l + (1 << (i - 1))]);
ST[1][i][l] = std::min(ST[1][i - 1][l], ST[1][i - 1][l + (1 << (i - 1))]);
}
}
for (rg int i = 1; i <= n; ++i) {
ans = std::max(q * MU[i] + p * ask(1, i, p < 0) + r * ask(i, n, r < 0), ans);
}
qw(ans, '\n', true);
return 0;
}
ll ask(ci l, ci r, ci cur) {
int len = r - l + 1;
if (cur) return std::min(ST[1][LOG[len]][l], ST[1][LOG[len]][r - (1 << LOG[len]) + 1]);
else return std::max(ST[0][LOG[len]][l], ST[0][LOG[len]][r - (1 << LOG[len]) + 1]);
}
Summary
这次貌似也没啥好summary的……就是我好菜啊ST都调了半天
【ST】【CF855B】 Marvolo Gaunt's Ring的更多相关文章
- Codeforces 855B - Marvolo Gaunt's Ring
855B - Marvolo Gaunt's Ring 思路:①枚举a[j],a[i]和a[k]分别用前缀最小值最大值和后缀最小值和后缀最大值确定. ②dp,dp[i][j]表示到第j为止,前i+1个 ...
- Marvolo Gaunt's Ring(巧妙利用前后缀进行模拟)
Description Professor Dumbledore is helping Harry destroy the Horcruxes. He went to Gaunt Shack as h ...
- B. Marvolo Gaunt's Ring 前缀后缀
B. Marvolo Gaunt's Ring 这种一般只有三个的都可以处理前缀和后缀,再枚举中间这个值. 这个和之前写过的C. Four Segments 前缀后缀 处理方式很像. #include ...
- Codeforces 855B:Marvolo Gaunt's Ring(枚举,前后缀)
B. Marvolo Gaunt's Ring Professor Dumbledore is helping Harry destroy the Horcruxes. He went to Gaun ...
- 【CF Manthan, Codefest 17 B】Marvolo Gaunt's Ring
[链接]h在这里写链接 [题意] 给你n个数字; 让你在其中找出三个数字i,j,k(i<=j<=k); 使得p*a[i]+q*a[j]+r*a[k]最大; [题解] /* 有一个要 ...
- POJ 3264 Balanced Lineup 【ST表 静态RMQ】
传送门:http://poj.org/problem?id=3264 Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total S ...
- bzoj 1699: [Usaco2007 Jan]Balanced Lineup排队【st表||线段树】
要求区间取min和max,可以用st表或线段树维护 st表 #include<iostream> #include<cstdio> using namespace std; c ...
- 【ST开发板评测】Nucleo-F411RE开箱报告
前言 面包板又举办开发板试用活动了,很荣幸能获得一块ST官方的Nucleo-F411RE开发板,感谢面包板社区和ST意法半导体的赞助,这是我第一次试用官方的开发板,收到板子后查了一些关于ST官方开发板 ...
- 【ST开发板评测】使用Python来开发STM32F411
前言 板子申请了也有一段时间了,也快到评测截止时间了,想着做点有意思的东西,正好前一段时间看到过可以在MCU上移植MicroPython的示例,就自己尝试一下,记录移植过程. MicroPython是 ...
随机推荐
- 03-运行第一个docker容器
环境选择 容器需要管理工具.runtime 和操作系统,我们的选择如下: 1.管理工具 - Docker Engine因为 Docker 最流行使用最广泛. 2.runtime - runc Dock ...
- MySql面试题(持续更新)
1. 左连接,右连接,内连接的概念. 左连接:以左表为主,保留左表的所有数据,并且依次拿每行数据去匹配右表所有行,如果没匹配的,右边表的数据为null. 右连接:以右表为主,保留右表的所有数据,并且依 ...
- 关于购买Redis服务器:腾讯云、阿里云还是华为云?
个人分类: redis使用 编辑 新年伊始,很多商家都开始进行新年产品大促销,在分布是缓存Redis领域,几家大公司也是打得如火如荼,各有千秋啊. 现在市场上比较有口碑的商家有腾讯云.阿里云.华为云三 ...
- sqlmap+tor解决ip黑名单限制
1.安装tor浏览器(8.0.8)并配置好 旧版tor是需要Vidalia配合的,新版貌似集成了?还是怎样的,反正不需要了 2.启动tor浏览器 3.启动sqlmap python sqlmap.py ...
- 使用appcmd命令创建iis站点及应用程序池
参考文章:iis7 appcmd的基础命令及简单用法 验证环境:Windows 7 IIS7 AppCmd.exe工具所在目录 C:\windows\sytstem32\inetsrv\目录下, ...
- KETTLE监控
kettle单实例环境下自身没有监控工具,但在集群下自带了监控工具. 一.集群自带的监控 kettle自带的集群监控工具可以监控转换的执行情况. 配置好集群后,打开浏览器:输入http://local ...
- SVN服务器搭建及客户端配置
为什么要使用SVN? 在程序的编写过程中,每个程序员都会负责开发一个或多个模块,且开发中会生成很多不同的版本, 这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subvers ...
- curl和file_get_contents 区别以及各自的优劣
PHP中fopen,file_get_contents,curl函数的区别: 1.fopen /file_get_contents 每次请求都会重新做DNS查询,并不对 DNS信息进行缓存.但是CUR ...
- 寻找bug
bug1:void不应有返回值. bug2:while(n--)没有条件终止循环. bug3:size和data没有定义 bug4:arr 是sz 在大于0的情况下创建的 一定部位bull 下面的 ...
- 学霸系统UI部分功能规格说明书
发布人员:软件工程实践小队 发布内容:学霸系统UI部分功能规格说明书 版本:学霸V1.1版本 ◆Part 1:引言 1.1目的 本功能规格说明书的目的在于明确 ...