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. QC增加Test、Defect字段

    QC--Tools--customization,在Project Entities中增加字段,在Project Lists中编辑Lookup List类型字段的指定值

  2. upc组队赛4 Go Latin

    Go Latin 题目描述 There are English words that you want to translate them into pseudo-Latin. To change a ...

  3. .net Windows Service 按装及遇到的问题

    一.注册方式1.cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ 2.按装:InstallUtil -i E:\WorkAll\Finance\t ...

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

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

  5. python字典拼接方法

    python的dict拼接有多种方法,其中一种很好用而且速度非常快: x = {**a, **b} 效果等价于: x = a.copy() x.update(b) 注意update()是没有返回值的 ...

  6. GetWindowsDirectoryA and GetSystemDirectory

    #include <iostream> #include <Windows.h> using std::cout; using std::endl; // 获取Windows文 ...

  7. Java的类加载器都有哪些,每个类加载器都有加载那些类,什么是双亲委派模型,是做什么的?

    类加载器按照层次,从顶层到底层,分为以下三种: (1)启动类加载器(Bootstrap ClassLoader) 这个类加载器负责将存放在JAVA_HOME/lib下的,或者被-Xbootclassp ...

  8. JavaWeb开发之一《Tomcat服务器的部署、安装及应用》

    搬以前写的博客[2014-12-10 21:43] 这几天做了一个Java的程序,然后先把他搭载到Web上,于是学习了基于Tomcat服务器的web开发,这里回顾一下Tomcat服务器的搭建过程. 1 ...

  9. idea激活教程,最新!!!

    1.下载破解补丁(关键). 破解补丁:JetbrainsIdesCrack-4.2-release.jar百度云地址:https://pan.baidu.com/s/18ovphd7sm7oYXQb4 ...

  10. liunx下在线安装mysql

    一:在线安装mysql 1.首先检测一下,mysql之前有没有被安装 命令:rpm -qa | grep mysql 2.删除mysql的命令: rpm -e --nodeps `rpm -qa | ...