牛客多校第四场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. python 错误类型

  2. [自考]C++中一些特殊用法 2016-10-16 22:12 318人阅读 评论(30) 收藏

    做了一段时间的C++的试题了,总结一些这段时间经常犯错和需要注意的地方. 一.常用的保留字和符号 const 定义常量或者参数 void 定义空类型变量或空类型指针,或指定函数没有返回值 static ...

  3. json 2016-09-18 22:03 207人阅读 评论(18) 收藏

    JSON:JavaScript 对象表示法(JavaScript Object Notation) JSON是什么? JSON(JavaScript Object Notation) 是一种轻量级的数 ...

  4. IP应用加速 – DCDN迈入全栈新篇章

    4月11日,第七届"亚太内容分发大会"暨CDN峰会国际论坛中,阿里云资深技术专家姚伟斌发布了DCDN子产品IP应用加速(IPA).IPA是基于阿里云CDN本身的资源优化,对传输层( ...

  5. 关于编码的发展演变:ASCII、GB2312、GBK、gb18030、Unicode、UTF-8

    [1]ASCII 每个字符占据1bytes(字节),第一次以规范标准发表是在1967年,最后一次修订是在1986年.用二进制表示的话最高位必须为0(扩展的ASCII不在考虑范围内),因此ASCII只能 ...

  6. oracle函数 TO_CHAR(x[[,c2],C3])

    [功能]将日期或数据转换为char数据类型 [参数] x是一个date或number数据类型. c2为格式参数 c3为NLS设置参数 如果x为日期nlsparm=NLS_DATE_LANGUAGE 控 ...

  7. CentOs7.0安装scrapy (云服务器上)

    centos7 默认Python 2.7,支持twisted 首先准备环境 yum install gcc libffi-devel openssl-devel libxml2 libxslt-dev ...

  8. 17-1 djanjo进阶-路由,视图,模板

    一 路由系统进阶(urls.py) 动态路由 urls.py中通过正则表达式的分组匹配,捕获用户访问的url中的值,传递给视图函数1 分组匹配(通过圆括号): 相当于给视图函数传递 位置参数 例子: ...

  9. AtCoder Regular Contest 059

    C - いっしょ / Be Together 数据比较小,暴力就挺好的.O(n^2)可过的好题 #include <bits/stdc++.h> using namespace std; ...

  10. protobuf_1

    我使用的是最新版本的protobuf(protobuf-2.6.1),编程工具使用VS2010.简单介绍下google protobuf: google protobuf 主要用于通讯,是google ...