传送门

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 longtypedef 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都调了半天

转载于:https://www.cnblogs.com/yifusuyi/p/10085164.html

【ST】【CF855B】 Marvolo Gaunt's Ring相关推荐

  1. Marvolo Gaunt's Ring 【CodeForces 855B】

    Marvolo Gaunt's Ring 求p * i + q * j + r * k(i<=j<=k)的最大值 虽然题中给的时间比较长但还是不可以用直接暴力用三次for循环,一定可以用一 ...

  2. B. Marvolo Gaunt’s Ring (递推)

    B. Marvolo Gaunt's Ring 题目链接 大致题意: 给你三个数 p,q,r,然后给你给你一个有序的序列,让你在序列中跳出三个数i,j,k(i <=j<=k)使得 p*a[ ...

  3. Marvolo Gaunt's Ring(类似于dp的做法)

    题目:(题目传送门) Professor Dumbledore is helping Harry destroy the Horcruxes. He went to Gaunt Shack as he ...

  4. Marvolo Gaunt's Ring ---CodeForces - 855B(思维题)

    题目链接:http://codeforces.com/problemset/problem/855/B Marvolo Gaunt's Ring Professor Dumbledore is hel ...

  5. Codeforces 855B - Marvolo Gaunt's Ring

    855B - Marvolo Gaunt's Ring 思路:①枚举a[j],a[i]和a[k]分别用前缀最小值最大值和后缀最小值和后缀最大值确定. ②dp,dp[i][j]表示到第j为止,前i+1个 ...

  6. Marvolo Gaunt's Ring CodeForces - 855B+线段树+维护区间最大值和最小值

    题目链接: Marvolo Gaunt's Ring CodeForces - 855B 题目大意: 给定一段序列:a1,a2,a3,--an, 给定三个数:p,q,r(注意数据范围,代码里ans=- ...

  7. 【JSOI2016】【st表/猫树】【枚举】灯塔

    [题目描述] [思路] 这道题也很不错.首先这道题有O(nlog⁡n)O(n\log n)O(nlogn)做法,但是我不会,我就只会O(nn)O(n \sqrt n)O(nn​)+卡常的做法.这道题唯 ...

  8. 【st表/猫树】【堆+贪心】超级钢琴

    [描述] 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中A ...

  9. bzoj 1699: [Usaco2007 Jan]Balanced Lineup排队【st表||线段树】

    要求区间取min和max,可以用st表或线段树维护 st表 #include<iostream> #include<cstdio> using namespace std; c ...

最新文章

  1. Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理,子集反演)
  2. FluxSink实例及解析
  3. 数字滤波器的幅频响应
  4. Android类库介绍
  5. 苹果系统中国日历服务器,AppleMac苹果电脑最好用的中国农历日历(TinyCal)v1.11.0
  6. 《机器人学经典教程》——2.1 控制理论
  7. 高效配置Linux代理服务器――Squid
  8. python头像右上角加红色数字_利用python实现微信头像加红色数字功能
  9. Hibernate 中 set 里的属性及定义
  10. 最新最全linux系统调优指南(centos7.X)
  11. 数字图像处理(matlab版)第三版,数字图像处理及MATLAB实现(第3版)
  12. Linux-虚拟机封装
  13. 微信小程序轮播图调用接口
  14. 耳机插入电脑的,耳机接口,却没有声音的 解决方法
  15. java抽象类变量_Java抽象类
  16. 计算机网络常见面试题汇总(建议收藏)
  17. python的增添删除查询列表
  18. 单片机数码管6位时钟c语言,单片机6位数码管时钟
  19. 如何利用CRM进行规范化商机管理?
  20. deepin efi 启动u盘_【2017.12.16】启动U盘简单手动制作BIOS+UEFI的syslinux/grub/boomgr/grub2互转...

热门文章

  1. 商城、门户、微信服务平台、CMS、易企秀、红包、分销商城、游戏源代码
  2. 判断两个向量是否平行
  3. 生产计划体系完整解决方案(2) : 复杂大规模问题之 - 分区规划
  4. Linux读取文件内容命令
  5. 关于月亮双鱼,早已超越弱与强。
  6. 司创电梯发卡软件_防复制电梯IC卡系统上位机管理软件设计
  7. 安卓和php接口数据传输加密,安卓与PHP间的RSA(openssl)交互加密的坑
  8. sip客户端源码c语言,SIP客户端选型
  9. 网络广告的过去、现在和未来
  10. 美国主流网站所使用的JavaScript框架