NC20806 区区区间间间
NC20806 区区区间间间
题目
题目描述
给出长度为n的序列a,其中第i个元素为 \(a_i\),定义区间(l,r)的价值为
\(v_{l,r} = max(a_i - a_j | l \leqslant i,j\leqslant r)\)
请你计算出 \(\sum_{l = 1}^n \sum_{r = l + 1}^n v_{l,r}\)
输入描述
第一行输入数据组数T
对于每组数据,第一行为一个整数n,表示序列长度
接下来一行有n个数,表示序列内的元素
输出描述
对于每组数据,输出一个整数表示答案
示例1
输入
3
3
4 2 3
5
1 8 4 3 9
20
2 8 15 1 10 5 19 19 3 5 6 6 2 8 2 12 16 3 8 17
输出
5
57
2712
说明
对于一组测试数据的解释:
区间[1, 2]的贡献为:4 - 2 = 2
区间[1, 3]的贡献为:4 - 2 = 2
区间[2, 3]的贡献为:3 - 2 = 1
2 + 1 + 2 = 5.
备注:
\(T \leqslant 20,n\leqslant 10^5, 0 \leqslant a_i \leqslant 10^5\)
不保证数据随机生成!
题解
思路
知识点:单调栈。
\(\sum_{l = 1}^n \sum_{r = l + 1}^n v_{l,r} = \sum_{l = 1}^n \sum_{r = l + 1}^n (max_{l,r} - min_{l,r})\) ,即所有子区间最大值之和减去所有子区间最小值之和。枚举端点用单调队列维护最小最大值,复杂度是 \(O(n^2)\)。换一个角度考虑,把每个元素当作最大/最小值,看看能维持左右多长,再将端点数相乘即可,这里用单调栈维护最邻近大于/小于。
细节上注意,以最大值为例,如果两个相同的元素,!s1.empty() && a[s1.top()] <= a[i] 都用小于等于作为弹出条件,那么这两个元素的扩展区间是完全相同的,从而左侧元素的右侧扩展和右侧元素的左侧扩展会有重复,因此保留一侧扩展而另一侧到小于等于就停,即 !s2.empty() && a[s2.top()] < a[i] 。
并且长度为 \(1\) 的区间不能算入其中,因此区间总数是 \((r[i] - i + 1) * (i - l[i] + 1) - 1\) ,但是由于长度为一的区间在最大值减去最小值过程会被消去,因此不减一也行。
这里有个小技巧,找最邻近大于时,即最小值扩展距离,可以将原数组取相反数,此时最小的会变成最大的,可以用最大值的方式求取,最后答案取相反数即可。
时间复杂度 \(O(n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n;
int a[100007], l[100007], r[100007];
ll calc() {
stack<int> s1, s2;
for (int i = 0;i < n;i++) {
while (!s1.empty() && a[s1.top()] <= a[i]) s1.pop();
l[i] = s1.empty() ? 0 : s1.top() + 1;
s1.push(i);
}
for (int i = n - 1;i >= 0;i--) {
while (!s2.empty() && a[s2.top()] < a[i]) s2.pop();///防止相等元素重复计算
r[i] = s2.empty() ? n - 1 : s2.top() - 1;
s2.push(i);
}
ll sum = 0;
for (int i = 0;i < n;i++)
sum += (1LL * (r[i] - i + 1) * (i - l[i] + 1) - 1) * a[i];
return sum;
}
bool solve() {
cin >> n;
for (int i = 0;i < n;i++) cin >> a[i];
ll mx = calc();
for (int i = 0;i < n;i++) a[i] = -a[i];///取相反数,最小值变最大值可以用同一种操作
ll mn = -calc();
cout << mx - mn << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
NC20806 区区区间间间的更多相关文章
- 牛客网 223C 区区区间间间(单调栈)
题目链接:区区区间间间 题意:给出长度为n的数字序列ai,定义区间(l,r)的价值为, 请你计算出. 题解:单调栈求ai左边和右边第一个比它小的位置,需要减去ai的个数为$(R_i-i+1)*(i-L ...
- NowCoder--牛可乐发红包脱单ACM赛C_区区区间间间
题目链接:C_区区区间间间 思路:算贡献,求出每个数为当前最大值时所在的区间个数,和每个数为最小值的区间个数 和这个题有点类似 搭配食用效果更佳 点击这里 #include<bits/stdc+ ...
- 牛客ACM赛 C 区区区间间间
链接 C 区区区间间间 给定长度为\(n\)序列,求\[\sum_{i=1}^{n} \sum_{j=i}^{n} max-min\] 其中\(max\),\(min\)为区间最大,最小值,\(n\l ...
- 牛客网 牛可乐发红包脱单ACM赛 C题 区区区间间间
[题解] 我想到了两种解法. 一种是扫描线+线段树+单调栈. 另一种方法是O(n)的,比较巧妙. 考虑每个数在哪些区间可以作为最小数.最长的区间就是它向左右走,直到有数字比它小,这个可以用单调栈维护. ...
- [nowcoderACM_223C][区区区间间间]
题目链接 思路 考虑用单调栈,栈顶为最大元素.当得到一个新值得时候,将这个值宇栈顶比较.因为栈顶是前面的最大元素.所以只要当前元素比栈顶大,那么肯定比前面的都大.只要将这个元素乘上前面的个数就行了. ...
- TZOJ 5694 区间和II(树状数组区间加区间和)
描述 给定n个整数,有两个操作: (1)给某个区间中的每个数增加一个值: (2)查询某个区间的和. 输入 第一行包括两个正整数n和q(1<=n, q<=100000),分别为序列的长度和操 ...
- LibreOJ 6280 数列分块入门 4(分块区间加区间求和)
题解:分块的区间求和比起线段树来说实在是太好写了(当然,复杂度也高)但这也是没办法的事情嘛.总之50000的数据跑了75ms左右还是挺优越的. 比起单点询问来说,区间询问和也没有复杂多少,多开一个su ...
- LibreOJ 6283 数列分块入门 7(区间加区间乘区间求和)
题解:这道题要打一个乘标记一个加标记,两个标记的优先级是乘法高,所以在乘的时候要将加标记同时乘上一个c,当然,对于每个非完整块一定要记得暴力重构整个块,把加标记和乘标记都初始化. 代码如下: #inc ...
- 使用IBM SVC构建vSphere存储间集群
使用IBM SVC构建vSphere存储间集群 本文目的 本文描述利用IBM SVC来构建Vsphere 存储间集群 解决方案 什么是vMSC? vShpere存储间集群是一个针对VmwarevSpe ...
随机推荐
- ArcGIS使用技巧(五)——批量裁剪
新手,若有错误还请指正! 最近用到了,所以记下来,用同一矢量范围裁剪多幅栅格数据.用到了ArcGIS中的迭代模型(图1): 图 1 首先,需要做一个准备工作,就是把需要裁剪的栅格数据放在同一数据库中( ...
- 从小白到侠客的 Windows 快捷键宝典
"天下 武功,唯快不破."你是否羡慕过那些电脑键盘侠客,他们操作起电脑行云流水,任务完成的又快又准.这到底是怎么做到的呢?我们是否也能向他们一样达到把键盘操作熟记于心呢?那就跟着笔 ...
- 攻防世界-MISC:Training-Stegano-1
这是攻防世界高手进阶区的题目,题目如下: 点击下载附件一,得到一张bmp图片 尝试用stegslove打开,并没有得到什么有用的信息,用010editor打开,发现文件后面有一串字符串 尝试提交fla ...
- vuepress搭建UI组件库文档踩坑篇
为了实现组件效果预览及代码展示可折叠功能,使用了插件vuepress-plugin-demo-container 相关配置可参考官网说明文档 第一步 安装插件 npm i - D vuepress-p ...
- slice-substring-substr-split-splice
一.字符串slice(startIndex, endBeforeIndex) endBeforeIndex < 0,则 endBeforeIndex 为 负数,第二个参数为字符串长度加上负值,之 ...
- 在字节跳动,一个更好的企业级SparkSQL Server这么做
SparkSQL是Spark生态系统中非常重要的组件.面向企业级服务时,SparkSQL存在易用性较差的问题,导致难满足日常的业务开发需求.本文将详细解读,如何通过构建SparkSQL服务器实现使用效 ...
- OAuth2密码模式已死,最先进的Spring Cloud认证授权方案在这里
旧的Spring Security OAuth2停止维护已经有一段时间了,99%的Spring Cloud微服务项目还在使用这些旧的体系,严重青黄不接.很多同学都在寻找新的解决方案,甚至还有念念不忘密 ...
- ElasticSearch基础学习(SpringBoot集成ES)
一.概述 什么是ElasticSearch? ElasticSearch,简称为ES, ES是一个开源的高扩展的分布式全文搜索引擎. 它可以近乎实时的存储.检索数据:本身扩展性很好,可以扩展到上百台服 ...
- MySQL体系结构与数据类型
layout: post title: "MySQL体系结构与数据类型" date: 2018-02-26 categories: MySQL tags: MySQL 一.MySQ ...
- 安装Zabbix到CentOS(YUM)
运行环境 系统版本:CentOS 7 软件版本:Zabbix-4.2.1 硬件要求:无 安装过程 1.安装YUM-Zabbix存储库 [root@localhost ~]# rpm -Uvh http ...