题干:

N个整数组成的数组,定义子数组aii..ajj的宽度为:max(ai..aj) - min(ai..aj),求所有子数组的宽度和。

Input

第1行:1个数N,表示数组的长度。(1 <= N <= 50000) 
第2 - N + 1行:每行1个数,表示数组中的元素(1 <= Aii <= 50000)

Output

输出所有子数组的宽度和。

Sample Input

5
1
2
3
4
5

Sample Output

20

解题报告:

这题显然不能枚举区间然后分别计算,所以很多技巧根本不需要考虑(比如排序一下?)

然后我们考虑枚举每一个元素,计算他对答案的贡献。

记得去重,也就是,一边算 严格单调,一边是 不严格单调,这样就可以保证不重不漏。(像 5 1 2 1 3 3 这样的样例,算贡献时(2,4)这种区间 只需要算一次。所以单调栈的时候一边是严格单调,一边是不严格单调)这个去重的方法很巧妙啊、

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX = 50000 + 5;
ll a[MAX],maxx[MAX],minn[MAX];
int l[MAX],r[MAX],L[MAX],R[MAX];//左侧第一个比我小的,右侧第一个比我小的。
stack<int> sk;
int main()
{int n;cin>>n;for(int i = 1; i<=n; i++) scanf("%lld",a+i);//从左到右找第一个比我小的,所以从左到右维护一个单调递增栈。for(int i = 1; i<=n; i++) {while(!sk.empty() && a[sk.top()] > a[i]) sk.pop();if(sk.size()) l[i] = sk.top();else l[i] = 0;sk.push(i);
//      printf("%d %d\n",i,l[i]);}while(!sk.empty()) sk.pop();//从右到左找第一个比我小的,所以维护从右向左维护一个单调递减栈。for(int i = n; i>=1; i--) {while(!sk.empty() && a[sk.top()] >= a[i]) sk.pop();if(sk.size()) r[i] = sk.top();else r[i] = n+1;sk.push(i);
//      printf("%d %d\n",i,r[i]);}for(int i = 1; i<=n; i++) minn[i] = (r[i] - i - 1) * (i-l[i]-1) + (r[i]-l[i]-1);while(!sk.empty()) sk.pop();//从左到右找第一个比我大的,所以从左向右维护一个单调递减栈,for(int i = 1; i<=n; i++) {while(!sk.empty() && a[sk.top()] < a[i]) sk.pop();if(sk.size()) L[i] = sk.top();else L[i] = 0;sk.push(i);}while(!sk.empty()) sk.pop();for(int i = n; i>=1; i--) {while(!sk.empty() && a[sk.top()] <= a[i]) sk.pop();if(sk.size()) R[i] = sk.top();else R[i] = n+1;sk.push(i);}for(int i = 1; i<=n; i++) maxx[i] = (R[i] - i-1) * (i-L[i]-1) + (R[i]-L[i]-1);
//  printf("yingyingying\n");
//  for(int i = 1; i<=n; i++) {
//      printf("%lld %lld\n",minn[i],maxx[i]);
//  }ll ans = 0;for(int i = 1; i<=n; i++) {ans += a[i] * (maxx[i] - minn[i]);}printf("%lld\n",ans);return 0;
}

还有几个好的题解:(暂时还未看)

http://www.itdaan.com/blog/2017/09/18/fb224770ef3801dcce5fcac76c36b4df.html

http://www.itdaan.com/blog/2017/08/22/df09138e3e52fc862172e8c8875d95ff.html

【51Nod - 1215 】数组的宽度 (单调栈 或 分治 或 单调队列,算贡献,需去重)相关推荐

  1. 51nod 1215 数组的宽度

    N个整数组成的数组,定义子数组a[i]..a[j]的宽度为:max(a[i]..a[j]) - min(a[i]..a[j]),求所有子数组的宽度和.   Input 第1行:1个数N,表示数组的长度 ...

  2. 1215 数组的宽度

    1215 数组的宽度 题目来源: Javaman 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 收藏 关注 N个整数组成的数组,定义子数组a[i]..a[j]的宽度为:max(a[ ...

  3. [单调栈/差分/尺取/单调队列]Exercise Week5 A最大矩形+B魔法猫+C平衡字符串+D滑动窗口

    目录 A.[单调栈]最大矩形 题意 样例 思路 总结 代码 B.[差分]TT's Magic Cat 题意 样例 思路 总结 代码 C.[尺取]平衡字符串 题意 样例 思路 总结 代码 D.[单调队列 ...

  4. CodeForces - 1313C2 Skyscrapers (hard version)(单调栈+dp/分治)

    题目链接:点击查看 题目大意:给出 n 块连续的空地可以建造摩天大楼,政府有规定,每块地最高只能建 a[ i ] 的高度,同时每栋大楼需要满足一个规则,即每栋大楼的两侧不允许同时存在比自己高的大楼,输 ...

  5. [剑指offer][JAVA]面试题第[33]题[二叉搜索树的后序遍历][单调栈][递归分治]

    [问题描述][中等] 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果.如果是则返回 true,否则返回 false.假设输入的数组的任意两个数字都互不相同.参考以下这颗二叉搜索树:5/ ...

  6. Looksery Cup 2015 F. Yura and Developers(单调栈+二分+分治)(难*)

    题目链接 题意:给定一个数组,问有多少区间满足:去掉最大值之后,和是k的倍数. 思路:日后补. #include<bits/stdc++.h> using namespace std; t ...

  7. 将一个数组中的值按逆序重新排放。_六十五、下一个更大的数系列,单调栈解决方法...

    「@Author:Runsen」 ❝ 编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化. 「---- Runsen」 ❞ 据说,放张小姐姐觉得照片可以提高阅读量,图是来源学校 ...

  8. [BZOJ3238][AHOI2013]差异 [后缀数组+单调栈]

    题目地址 - GO-> 题目大意: 给定一个长度为 nn 的字符串SS,令TiTi表示它从第ii个字符开始的后缀,求以下这个式子的值: ∑1≤i<j≤nlen(Ti)+len(Tj)−2× ...

  9. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 2326  Solved: 1054 [Submit][Stat ...

最新文章

  1. 关于xib里面的NSLayoutConstraint的multiplier修改
  2. 开源 python_8款Python GUI开源框架,谁才是你的最爱?
  3. libevent源码分析:eventop
  4. 《java练习题》习题集二
  5. Java EE 7批处理和魔兽世界–第2部分
  6. fork()使用(一)
  7. mmap函数_Linux内存映射mmap原理分析
  8. 支付宝二面微服务、分布式架构?太真实了!
  9. ubuntu 16卸载mysql_ubuntu16.04 彻底卸载MySQL
  10. 文章采集伪原创工具_伪原创文章技巧(如何提高伪原创文章的原创度)
  11. python选择日期控件_Python3 自己写了个DateCtrl日期控件 | 学步园
  12. Netscape 重构软件倒闭了,但我仍坚定地站重写!
  13. 用dsp的c54x汇编语言编写4位数的按位输出和计算,DSP实验三实验四(精).doc
  14. Scanner、String(java基础知识十二)
  15. 楚留香ai识别人脸_【专利解密】商汤科技:AI加持人脸识别
  16. 小学生python游戏编程6----碰边变颜色的小球
  17. 用友U8打开起初采购入库单报错
  18. 手把手教你电脑下载b站视频
  19. 利用Python自动生成小学生加减乘除口算考试题卷
  20. 项目管理与敏捷开发-流程之间的区别

热门文章

  1. 121 Best Time to Buy and Sell Stock
  2. 【Breadth-first Search 】专题3
  3. [剑指offer]面试题第[59-2]题[JAVA][队列的最大值][暴力][双端队列]
  4. 【模板】最新空web.xml模板
  5. 940B. Our Tanya is Crying Out Loud
  6. Oracle删除pk+cascade,Oracle删除表
  7. js 多个定时器_JS中的同步/异步编程
  8. asp.net 设置 excel alignment_教你如何用Python轻轻松松操作Excel、Word、CSV,一文就够了,赶紧码住!!!...
  9. Qt 编码问题QTextCodec
  10. wince中BIB文件的详细介绍