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. Kubernetes 技能图谱skill-map

    # Kubernetes 技能图谱 ## Container basics (容器技术基础)* Kernel* Cgroups* Userspace runtime* Image* Registry ...

  2. (10)C++ 使用类

    一.运算符重载 1. #include<iostream> using namespace std; class Sum { int add; public: Sum(int add) { ...

  3. 将libvex移植到Visual Studio编译平台下的经验总结

    1. 两难 将libvex从Linux移植到Windows,移植工作聚集于Cross-Compiler,而不是预料的Cross-Platform. VC++ Compiler到目前为止只支持C89标准 ...

  4. 点读系列《jmeter官方用户手册》

    官网:http://jmeter.apache.org/usermanual/ 说明:十八元件.十九属性.二十函数,涉及清单内容暂未仔细阅读,个人觉得一是仅供使用参考,二是适合单独写文章来解读 一.让 ...

  5. mysqldump备份和恢复

    一.备份单个数据库 1.备份命令:mysqldump MySQL数据库自带的一个很好用的备份命令.是逻辑备份,导出 的是SQL语句.也就是把数据从MySQL库中以逻辑的SQL语句的形式直接输出或生成备 ...

  6. Pytest 通过文件名类名方法执行部分用例

    • 场景:只执行符合要求的某一部分用例,通过类与方法的命名实 现.通常编写测试方法时 • 解决:直接输入文件名,类名 pytest test_class_01.py • pytest -v -s te ...

  7. linux CentOS7 安装 Java

    1. http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html先去下载 java 对应的 ...

  8. linux基础文件管理软硬链接

    一.文件系统的基本结构 1.文件和目录被组成一个单根倒置树目录结构 2.文件系统从根目录下开始,用“/”表示 3.根文件系统(rootfs):root filesystem文件名区分大小写 4.以 . ...

  9. JavaScript_DOM详解

    节点操作: 查看对象属性的值obj.getAttribute() 如: //获取图片 var imgs = document.getElementsByTagName("img") ...

  10. JS window对象 返回下一个浏览的页面 forward()方法,加载 history 列表中的下一个 URL。

    返回下一个浏览的页面 forward()方法,加载 history 列表中的下一个 URL. 如果倒退之后,再想回到倒退之前浏览的页面,则可以使用forward()方法,代码如下: window.hi ...