牛客多校第四场sequence C (线段树+单调栈)

传送门:https://ac.nowcoder.com/acm/contest/884/C

题意:

求一个$$ \max {1 \leq l \leq r \leq n}\left{\min \left(a{l \dots r}\right) \times \operatorname{sum}\left(b_{l \dots r}\right)\right} $$

题解:

枚举最小值

最大值可能有两种情况:两个正数相乘,两个负数相乘,我们先讨论正数相乘的情况

对于当前的\(a_i\)我们可以利用单调栈找到左边第一个比他小的数\(a_l\)和右边第一个比他小的数\(a_r\)

那么在区间\([l+1,r-1]\)的区间最小值就是\(a_i\)

我们现在已知\(a_i\)在区间内已经是最小的了,所以为了得到最大值,我们需要得到\(sum(b_{l...r})\)的最大值

将区间分为两个部分\([l+1,i]和[i,r-1]\)那么\(sum(b_{l..r})\)的最大值就是右边部分最大的前缀和减去左边部分最小的前缀和即可

对于负数相乘的情况

\(sum(b_{l...r})\)的最大值就是右边部分的最小的前缀和减去左边部分的最大前缀和即可

代码:

/**
*        ┏┓    ┏┓
*        ┏┛┗━━━━━━━┛┗━━━┓
*        ┃       ┃  
*        ┃   ━    ┃
*        ┃ >   < ┃
*        ┃       ┃
*        ┃... ⌒ ...  ┃
*        ┃       ┃
*        ┗━┓   ┏━┛
*          ┃   ┃ Code is far away from bug with the animal protecting          
*          ┃   ┃ 神兽保佑,代码无bug
*          ┃   ┃           
*          ┃   ┃       
*          ┃   ┃
*          ┃   ┃           
*          ┃   ┗━━━┓
*          ┃       ┣┓
*          ┃       ┏┛
*          ┗┓┓┏━┳┓┏┛
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛
*/
// warm heart, wagging tail,and a smile just for you!
//
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// .' \| |// `.
// / \||| : |||// \
// / _||||| -:- |||||- \
// | | \ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// 佛祖保佑 永无BUG
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e6 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
LL gcd(LL a, LL b) {
return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
return a / gcd(a, b) * b;
}
double dpow(double a, LL b) {
double ans = 1.0;
while(b) {
if(b % 2)ans = ans * a;
a = a * a;
b /= 2;
} return ans;
}
LL quick_pow(LL x, LL y) {
LL ans = 1;
while(y) {
if(y & 1) {
ans = ans * x % mod;
} x = x * x % mod;
y >>= 1;
} return ans;
}
int stal[maxn], star[maxn], sta[maxn];
LL a[maxn];
LL b[maxn];
LL Max[maxn << 2];
LL Min[maxn << 2];
LL sum[maxn];
void push_up(int rt) {
Max[rt] = max(Max[ls], Max[rs]);
Min[rt] = min(Min[ls], Min[rs]);
}
void build(int l, int r, int rt) {
Max[rt] = 0;
Min[rt] = INF;
if(l == r) {
Max[rt] = sum[l];
Min[rt] = sum[l];
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
push_up(rt);
} LL query_max(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return Max[rt];
}
int mid = (l + r) >> 1;
LL ans = 0;
if(L <= mid) {
ans = max(ans, query_max(L, R, lson));
}
if(R > mid) {
ans = max(ans, query_max(L, R, rson));
}
return ans;
}
LL query_min(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return Min[rt];
}
int mid = (l + r) >> 1;
LL ans = INF;
if(L <= mid) {
ans = min(ans, query_min(L, R, lson));
}
if(R > mid) {
ans = min(ans, query_min(L, R, rson));
}
return ans;
} int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
sum[0] = 0;
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
}
for(int i = 1; i <= n; i++) {
scanf("%lld", &b[i]);
sum[i] = sum[i - 1] + b[i];
}
LL ans = -INF;
int l = 0, r = 0;
while(l <= n && r <= n) {
while(a[l] <= 0 & l <= n) l++;
if(a[l] > 0) {
r = l;
while(a[r + 1] > 0) r++;
int top = 0;
sta[0] = l - 1;
for(int i = l; i <= r; i++) {
while(top > 0 && a[sta[top]] > a[i]) {
star[sta[top]] = i;//可以往右走的最远距离
top--;
}
sta[++top] = i;
stal[i] = sta[top - 1];//可以往左走的最远距离 }
while(top > 0) {
star[sta[top]] = r + 1;
top--;
}
for(int i = l; i <= r; i++) {
ans = max(ans, (sum[star[i] - 1] - sum[stal[i]]) * a[i]);
}
} else {
r = l;
}
l = r + 1;
}
build(0, n, 1);
for(int i = 1; i <= n; i++) {
if(a[i] < 0) {
LL maxx = query_max(0, i - 1, 0, n, 1);
LL minn = query_min(i, n, 0, n, 1);
ans = max(ans, (minn - maxx) * a[i]);
}
}
printf("%lld\n", ans);
return 0;
}

牛客多校第四场sequence C (线段树+单调栈)的更多相关文章

  1. 2019牛客多校第四场B xor——线段树&&线性基的交

    题意 给你 $n$ 个集合,每个集合中包含一些整数.我们说一个集合表示一个整数当且仅当存在一个子集其异或和等于这个整数.现在你需要回答 $m$ 次询问 ($l, r, x$),是否 $l$ 到 $r$ ...

  2. Explorer(2019年牛客多校第八场E题+线段树+可撤销并查集)

    题目链接 传送门 题意 给你一张无向图,每条边\(u_i,v_i\)的权值范围为\([L_i,R_i]\),要经过这条边的条件是你的容量要在\([L_i,R_i]\),现在问你你有多少种容量使得你可以 ...

  3. 2019牛客多校第七场C-Governing sand(线段树+枚举)

    Governing sand 题目传送门 解题思路 枚举每一种高度作为最大高度,则需要的最小花费的钱是:砍掉所有比这个高度高的树的所有花费+砍掉比这个高度低的树里最便宜的m棵树的花费,m为高度低的里面 ...

  4. 牛客多校第四场 G Maximum Mode

    链接:https://www.nowcoder.com/acm/contest/142/G来源:牛客网 The mode of an integer sequence is the value tha ...

  5. 牛客多校第四场 F Beautiful Garden

    链接:https://www.nowcoder.com/acm/contest/142/F来源:牛客网 题目描述 There's a beautiful garden whose size is n ...

  6. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

  7. 2019牛客多校第四场 A meeting

    链接:https://ac.nowcoder.com/acm/contest/884/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语言10485 ...

  8. 2019牛客多校第四场C-sequence(单调栈+线段树)

    sequence 题目传送门 解题思路 用单调栈求出每个a[i]作为最小值的最大范围.对于每个a[i],我们都要乘以一个以a[i]为区间内最小值的对应的b的区间和s,如果a[i] > 0,则s要 ...

  9. 【HDU】4092 Nice boat(多校第四场1006) ——线段树 懒惰标记

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) To ...

随机推荐

  1. 洛谷1014 Cantor表

      水题.随便搞搞就过了. //Serene #include<algorithm> #include<iostream> #include<cstring> #i ...

  2. LayUI+Echart实现图表

    1.首先 定义一个容器存放图表  需要指定这个容器的大小 <div class="layui-card"> <div class="layui-card ...

  3. linux下的远程数据库(Oracle)中文乱码问题

    适用于本地客户端(PLSQL Developer )访问远程数据库时,查询结果出现的乱码,当在远程数据库上查询结果时显示正常. 1.查询远程数据库的编码: select userenv('langua ...

  4. springboot web开发【转】【补】

    pom.xml引入webjars的官网 https://www.webjars.org/ https://www.thymeleaf.org/doc/tutorials/3.0/usingthymel ...

  5. SSH applicationContext.xml import异常

    近期在项目上,遇到了一个问题.在配置applicationContext.xml使用<import>标签引入其他的xml文件时,导致项目启动时过慢.有时还会引起启动异常.后来查到是xml文 ...

  6. phpexcel使用说明2

      转自:http://serisboy.iteye.com/blog/1928139 首先到phpexcel官网上下载最新的phpexcel类,下周解压缩一个classes文件夹,里面包含了PHPE ...

  7. sql:mysql:函数:TIMESTAMPDIFF函数实现TimeStamp字段相减,求得时间差

    函数内指定是minute,则最终结果value值的单位是分钟,如果函数内指定为hours,则最终结果value值单位为小时. //UPLOAD_TIME 减去 CREATE_DTTM 求得时间差,以分 ...

  8. 阿里靠什么支撑 EB 级计算力?

    作者 关涛 阿里云智能事业群 研究员 导读:MaxCompute 是阿里EB级计算平台,经过十年磨砺,它成为阿里巴巴集团数据中台的计算核心和阿里云大数据的基础服务.去年MaxCompute 做了哪些工 ...

  9. linux下修改gcc编译器版本

    可以使用如下命令行来让 gcc 选择不同的 C++ 版本: g++ -std=c++11 main.cpp 在你的系统中,由于编译器或是编译器设定上的差别,操作也许有所不同.    

  10. Facebook 发布深度学习工具包 PyTorch Hub,让论文复现变得更容易

    近日,PyTorch 社区发布了一个深度学习工具包 PyTorchHub, 帮助机器学习工作者更快实现重要论文的复现工作.PyTorchHub 由一个预训练模型仓库组成,专门用于提高研究工作的复现性以 ...