sequence

题目传送门

解题思路

用单调栈求出每个a[i]作为最小值的最大范围。对于每个a[i],我们都要乘以一个以a[i]为区间内最小值的对应的b的区间和s,如果a[i] > 0,则s要尽量大,如果a[i] < 0,则s要尽量小。因为一段区间的和可以利用前缀和c[]相减求出,而以a[i]为最小值的区间和为:c[i~r] - c[l-1~i-1]。 所以用b[i]的前缀和建立线段树,维护其最大最小值。要求最大的s,即为求ir内的最大前缀和与l-1i-1范围内的最小前缀和。求最小的s同理。

代码如下

#include <bits/stdc++.h>
#define INF 5223372036854775807LL
using namespace std;
typedef long long ll; inline int read(){
int res = 0, w = 0; char ch = 0;
while(!isdigit(ch)){
w |= ch == '-', ch = getchar();
}
while(isdigit(ch)){
res = (res << 3) + (res << 1) + (ch ^ 48);
ch = getchar();
}
return w ? -res : res;
} const int N = 3000005; ll a[N], b[N];
ll c[N];
struct T{
int l, r;
ll maxx, minn;
}tree[N<<2]; void build(int k, int l, int r)
{
tree[k].l = l;
tree[k].r = r;
if(l == r){
tree[k].maxx = tree[k].minn = c[l];
return;
}
int mid = (l + r) / 2;
build(2*k, l, mid);
build(2*k+1, mid + 1, r);
tree[k].maxx = max(tree[2*k].maxx, tree[2*k+1].maxx);
tree[k].minn = min(tree[2*k].minn, tree[2*k+1].minn);
} ll query_minn(int k, int l, int r)
{
if(tree[k].l >= l && tree[k].r <= r)
return tree[k].minn;
int mid = (tree[k].l + tree[k].r) / 2;
ll m1 = INF, m2 = INF;
if(l <= mid)
m1 = query_minn(2*k, l, r);
if(r > mid)
m2 = query_minn(2*k+1, l, r);
return min(m1, m2);
} ll query_maxx(int k, int l, int r)
{
if(tree[k].l >= l && tree[k].r <= r)
return tree[k].maxx;
int mid = (tree[k].l + tree[k].r) / 2;
ll m1 = -INF, m2 = -INF;
if(l <= mid)
m1 = query_maxx(2*k, l, r);
if(r > mid)
m2 = query_maxx(2*k+1, l, r);
return max(m1, m2);
} int l[N], r[N];
int dq[N]; int main()
{
int n;
n = read();
for(int i = 1; i <= n; i ++)
a[i] = read();
for(int i = 1; i <= n; i ++)
b[i] = read();
for(int i = 1; i <= n; i ++)
c[i] = c[i - 1] + b[i];
build(1, 1, n);
int ql, qr;
ql = qr = 0;
for(int i = 1; i <= n; i ++){
while(ql != qr && a[dq[qr - 1]] >= a[i])
qr --;
if(ql != qr)
l[i] = dq[qr - 1] + 1;
else
l[i] = 1;
dq[qr++] = i;
}
ql = qr = 0;
for(int i = n; i >= 1; i --){
while(ql != qr && a[dq[qr - 1]] >= a[i])
qr --;
if(ql != qr)
r[i] = dq[qr - 1] - 1;
else
r[i] = n;
dq[qr++] = i;
}
ll ans = -INF;
for(int i = 1; i <= n; i ++){
if(a[i] < 0){
ans = max(ans, a[i] * (query_minn(1, i, r[i]) - query_maxx(1, l[i] - 1, i - 1)));
}
else if(a[i] > 0){
ans = max(ans, a[i] * (query_maxx(1, i, r[i]) - query_minn(1, l[i] - 1, i - 1)));
}
else
ans = max(ans, 0LL);
}
cout << ans << endl;
return 0;
}

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

  1. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  2. 牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)

    题目传送门:https://www.nowcoder.com/acm/contest/142/J 题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法. 分析: eg.对于序列{ ...

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

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

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

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

  5. 牛客多校第十场 A Rikka with Lowbit 线段树

    链接:https://www.nowcoder.com/acm/contest/148/A来源:牛客网 题目描述 Today, Rikka is going to learn how to use B ...

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

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

  7. 2019牛客多校第四场J free——分层图&&最短路

    题意 一张无向图,每条边有权值,可以选择不超过 $k$ 条路使其权值变成0,求 $S$ 到 $T$ 的最短路.(同洛谷 P4568) 分析 首先,分层图最短路可以有效解决这种带有 「阶段性」的最短路, ...

  8. 2019牛客多校第四场A meeting——树的直径

    题意: 一颗 $n$ 个节点的树上标有 $k$ 个点,找一点使得到 $k$ 个关键结点的最大距离最小. 分析: 问题等价于求树的直径,最小距离即为直径除2向上取整. 有两种求法,一是动态规划,对于每个 ...

  9. [2019牛客多校第四场][G. Tree]

    题目链接:https://ac.nowcoder.com/acm/contest/884/G 题目大意:给定一个树\(A\),再给出\(t\)次询问,问\(A\)中有多少连通子图与树\(B_i\)同构 ...

  10. 2019牛客多校第四场D-triples I 贪心

    D-triples 题意 给你一个\(n\),问至少有几个数或运算起来可以等于\(n\),并且输出数量和这个几个数.题目说明给的\(n\)一定符合条件(不会输出\(n= 1\) 之类不存在情况). 思 ...

随机推荐

  1. 用FastDFS一步步搭建图片服务器(单机版)

    一.FastDFS介绍 FastDFS开源地址:https://github.com/happyfish100 参考:分布式文件系统FastDFS设计原理 参考:FastDFS分布式文件系统 1.简介 ...

  2. jQuery.inArray()方法

    $.inArray() 函数用于在数组中查找指定值,并返回它的索引值(如果没有找到,则返回-1) 提示:源数组不会受到影响,过滤结果只反映在返回的结果数组中. 语法 $.inArray( value, ...

  3. HBase 入门之数据刷写(Memstore Flush)详细说明

    接触过 HBase 的同学应该对 HBase 写数据的过程比较熟悉(不熟悉也没关系).HBase 写数据(比如 put.delete)的时候,都是写 WAL(假设 WAL 没有被关闭) ,然后将数据写 ...

  4. Java语言基础及java核心

    一.Java语言特点 1. 简单 2. 面向对象 3. 分布式 4. 健壮 5. 安全 6. 中性架构跨平台 7. 超强的可移植性 8. 高性能 9. 多线程 二.java的环境变量 JAVA_HOM ...

  5. 从上一个页面跳入新页面时,如何拿URL中的参数

    var url = document.URL; //获取当前页面的url var urlA = url.split('?');//以url中的问号进行分割; var goodscode = urlA[ ...

  6. jumpserver注意事项以及报错处理

    需要注意下面亮点 在使用jumpserver过程中,有一步是系统用户推送,要推送成功,client(后端服务器)要满足以下条件: 后端服务器需要有python.sudo环境才能使用推送用户,批量命令等 ...

  7. Spring学习笔记(9)——注入参数

    集合类型属性 1.Set类型 private Set<String> sets=new HashSet<String>(); //我们需要给它添加set方法 public Se ...

  8. ionic2(3) 密码键盘组件 ionic2-pincode-input 使用

    1.效果展示: 2.安装: npm install ionic2-pincode-input --save 3.app.module.ts配置 app.module.ts import { NgMod ...

  9. 【记录】原生js日期格式化转换方法

    情况一:将日期转换为指定的格式:比如转换成 年月日时分秒 首先我们在js中定义函数如下 Date.prototype.format = function(fmt) { var o = { " ...

  10. Python 基础 2-1 列表入门

    引言 列表 list 是由一系列按照特定顺序排列的元素组成的,它是一种有序的数据集合. 你可以添加任何类型的元素到列表中,其中的元素之间可以没有任何关系. 列表简介 Python 使用方括号 [] 来 ...