[COCI2010-2011#3] DIFERENCIJA

题目描述

给出一个长度为 nnn 的序列 aia_iai​,求出下列式子的值:

∑i=1n∑j=inmax⁡i≤k≤jak−min⁡i≤k≤jak\sum_{i=1}^{n} \sum_{j=i}^{n} \max_{i\le k\le j} a_k-\min_{i\le k\le j} a_ki=1∑n​j=i∑n​i≤k≤jmax​ak​−i≤k≤jmin​ak​

即定义一个子序列的权值为序列内最大值与最小值的差。求出所有连续子序列的权值和。

输入格式

输入第一行一个整数 nnn,表示序列的长度。

接下来的 nnn 行,每行一个整数 aia_iai​,描述这个序列。

输出格式

输出一行一个整数,表示式子的答案。

样例 #1

样例输入 #1

3
1
2
3

样例输出 #1

4

样例 #2

样例输入 #2

4
7
5
7
5

样例输出 #2

12

样例 #3

样例输入 #3

4
3
1
7
2

样例输出 #3

31

提示

数据规模与约定

对于 100%100\%100% 的数据,保证 2≤n≤3×1052\le n\le 3\times 10^52≤n≤3×105,1≤ai≤1081\le a_i\le 10^81≤ai​≤108。

说明

题目译自 COCI2010-2011 CONTEST #3 T5 DIFERENCIJA

偷偷打开标签

单调队列\colorbox{darkblue}{\color{darkblue}\boxed{\begin{gathered}\begin{gathered}\small \color{white}{\text{ 单调队列}}\end{gathered}\cr\end{gathered}}} 单调队列​​​​栈\colorbox{darkblue}{\color{darkblue}\boxed{\begin{gathered}\begin{gathered}\small \color{white}{\text{ 栈}}\end{gathered}\cr\end{gathered}}} 栈​​​​COCI\colorbox{skyblue}{\color{skyblue}\boxed{\begin{gathered}\begin{gathered}\small \color{white}{\text{ COCI}}\end{gathered}\cr\end{gathered}}} COCI​​​​O2优化\colorbox{orange}{\color{orange}\boxed{\begin{gathered}\begin{gathered}\small \color{white}{\text{ O2优化}}\end{gathered}\cr\end{gathered}}} O2优化​​​​2010\colorbox{blue}{\color{blue}\boxed{\begin{gathered}\begin{gathered}\small \color{white}{\text{ 2010}}\end{gathered}\cr\end{gathered}}} 2010​​​​

那么,我们从哪方面入手?

How about 单调队列?

似乎麻烦,我不干

那栈呢

就试试看吧
先把他当最大的,然后最小
最大左边缘lmx 最大右边缘 rmx 最小左边缘 lmn 最小右边缘 rmn
然鹅,有一个大问题,画个图就知道

7 4 5 3 7
7-------》
《------7

有没有发现,两个7行走的路线有重复?

于是呢,我便发明了个好方法,就是左(右)区间可以右等于的,另一边不行
然后呢,样例没过

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[300007];
struct pd{int lmx,rmx,lmn,rmn;
}k[300007];
struct _stack_{int a[1000007],n;void push(int x){a[++n]=x;return;}void pop(){--n;return;}void clear(){n=0;}bool empty(){return (n==0);};int size(){return n;}int top(){return a[n];}
};
_stack_ lmx,rmx,lmn,rmn;
int ans;
signed main(){scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",a+i);for(int i=1;i<=n;i++){while(!lmx.empty()&&a[lmx.top()]<=a[i])lmx.pop();k[i].lmx=(!lmx.empty())?(lmx.top()):1;lmx.push(i);}for(int i=n;i>=1;i--){while(!rmx.empty()&&a[rmx.top()]<a[i])rmx.pop();k[i].rmx=(!rmx.empty())?(rmx.top()):n;rmx.push(i);}for(int i=1;i<=n;i++){while(!lmn.empty()&&a[lmn.top()]>=a[i])lmn.pop();k[i].lmn=(!lmn.empty())?(lmn.top()):1;lmn.push(i);}for(int i=n;i>=1;i--){while(!rmn.empty()&&a[rmn.top()]>a[i])rmn.pop();k[i].rmn=(!rmn.empty())?(rmn.top()):n;rmn.push(i);}for(int i=1;i<=n;i++){ans+=a[i]*((k[i].rmx-k[i].lmx+1)-(k[i].rmn-k[i].lmn+1));}printf("%lld",ans);return 0;
}

经过一番修改,我发现了如下的问题:

  1. 左右区间不合法的也判进去了
  2. 少了很多区间
    修改后的样子:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[300007];
struct pd{int lmx,rmx,lmn,rmn;
}k[300007];
struct _stack_{//手写栈int a[1000007],n;void push(int x){a[++n]=x;return;}void pop(){--n;return;}void clear(){n=0;}bool empty(){return (n==0);};int size(){return n;}int top(){return a[n];}
};
_stack_ lmx,rmx,lmn,rmn;
int ans;
signed main(){scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",a+i);for(int i=1;i<=n;i++){while(!lmx.empty()&&a[lmx.top()]<=a[i])lmx.pop();k[i].lmx=(!lmx.empty())?(lmx.top()+1):1;lmx.push(i);}for(int i=n;i>=1;i--){while(!rmx.empty()&&a[rmx.top()]<a[i])rmx.pop();k[i].rmx=(!rmx.empty())?(rmx.top()-1):n;rmx.push(i);}for(int i=1;i<=n;i++){while(!lmn.empty()&&a[lmn.top()]>=a[i])lmn.pop();k[i].lmn=(!lmn.empty())?(lmn.top()+1):1;lmn.push(i);}for(int i=n;i>=1;i--){while(!rmn.empty()&&a[rmn.top()]>a[i])rmn.pop();k[i].rmn=(!rmn.empty())?(rmn.top()-1):n;rmn.push(i);}for(int i=1;i<=n;i++){ans+=a[i]*((k[i].rmx-i+1)*(i-k[i].lmx+1)-(k[i].rmn-i+1)*(i-k[i].lmn+1));}printf("%lld",ans);return 0;
}

完美AC\colorbox{green}{\color{green}\boxed{\begin{gathered}\begin{gathered}\small \color{white}{\text{ AC}}\end{gathered}\cr\end{gathered}}} AC​​​​

洛谷P6503[COCI2010-2011#3] DIFERENCIJA相关推荐

  1. 洛谷 P1873 [COCI 2011/2012 #5] EKO / 砍树

    题目传送门: 洛谷 P1873 [COCI 2011/2012 #5] EKO / 砍树 题目描述 伐木工人 Mirko 需要砍 M 米长的木材.对 Mirko 来说这是很简单的工作,因为他有一个漂亮 ...

  2. 洛谷P1873 [COCI 2011/2012 #5] EKO / 砍树(二分法)

    题目链接 : 洛谷P1873 [COCI 2011/2012 #5] EKO / 砍树 文章目录 前言 一.题目 题目描述 输入格式 输出格式 输入输出样例 说明/提示 二.代码 前言 第一次写博客, ...

  3. 【C++】洛谷P1873 [COCI 2011/2012 #5] EKO / 砍树

    [COCI 2011/2012 #5] EKO / 砍树 题目描述 伐木工人 Mirko 需要砍 MMM 米长的木材.对 Mirko 来说这是很简单的工作,因为他有一个漂亮的新伐木机,可以如野火一般砍 ...

  4. 洛谷 P1873 [COCI 2011/2012 #5] EKO / 砍树 二分

    # [COCI 2011/2012 #5] EKO / 砍树 ## 题目描述 伐木工人 Mirko 需要砍 $M$ 米长的木材.对 Mirko 来说这是很简单的工作,因为他有一个漂亮的新伐木机,可以如 ...

  5. 洛谷P1873 [COCI 2011/2012 #5] EKO / 砍树

    题目描述 伐木工人 Mirko 需要砍 MM 米长的木材.对 Mirko 来说这是很简单的工作,因为他有一个漂亮的新伐木机,可以如野火一般砍伐森林.不过,Mirko 只被允许砍伐一排树. Mirko ...

  6. 洛谷P1130 红牌 动态规划

    洛谷P1130 红牌 动态规划 状态转移方程   dp[ j ][ i ] = dp[ j-1 ][ i-1 ] + dp[ j ][ i-1 ]   然后 1 的时候判一下就行 1 #include ...

  7. (差分)洛谷P4231 三步必杀

    洛谷P4231 三步必杀 三步必杀 题目背景 (三)旧都 离开狭窄的洞穴,眼前豁然开朗. 天空飘着不寻常的雪花. 一反之前的幽闭,现在面对的,是繁华的街市,可以听见酒碗碰撞的声音. 这是由被人们厌恶的 ...

  8. (树状数组+逆元)洛谷P5142 区间方差

    洛谷P5142 区间方差 (^ w ^) 题目背景 出题人并没有能力写有趣的题面-- 题目描述 对于一个长度为n的序列a1,a2,a3⋯ana_1,a_2,a_3\cdots a_na1​,a2​,a ...

  9. 洛谷 P7960 [NOIP2021] 报数

    PS:如果读过题了可以跳过题目描述直接到题解部分 提交链接:洛谷 P7960 [NOIP2021] 报数 题目 题目描述 报数游戏是一个广为流传的休闲小游戏.参加游戏的每个人要按一定顺序轮流报数,但如 ...

最新文章

  1. TableView的集合
  2. 给标签定义通用样式的css文件
  3. gitee最多上传多大文件_H5移动端图片压缩上传,基于Jquery的前端,实现拍照上传,选择相册
  4. ARM(IMX6U)裸机模仿STM32驱动开发实验(定义外设结构体)
  5. SqlServer三种常用窗口函数
  6. Windows应用程序进阶2(非模态对话框 通用对话框)
  7. 利用CSS3中的clac()实现按照屏幕分辨率自适应宽度
  8. 天马行空脚踏实地,阿里巴巴有群百里挑一的天才应届生...
  9. 如何制作朋友圈搞笑证件图片(附源码实例)
  10. 【C语言典例】——day8:猜名次
  11. 七大云架构设计在线绘图工具
  12. python笔记003
  13. python设计迷宫_用Python制作迷宫GIF
  14. 对象不可达,一定会被垃圾收集器回收么?
  15. android OTG (USB读写,U盘读写)最全使用相关总结
  16. 2年Java软件工程师的觉悟
  17. Linux操作系统的基础知识
  18. ant design pro 菜单图标引入问题 iconfontUrl inconfont图标本地
  19. 分享snopt优化工具箱matlab版
  20. Martian分析:轻量级微服务网络框架试用(Mars)

热门文章

  1. EDC大展览,你的EDC是什么呢
  2. 网易金融的“加减法”:如今仅剩支付和网络小贷
  3. 向百度提交网站地图Sitemap
  4. R语言时间序列中时间年、月、季、日的处理
  5. R语言 | 认识apply家族
  6. 给konva加个刻度尺
  7. 金融资金平台HTML模板
  8. 局域网乐趣之二:连接共享设置(示范系统windows2003)
  9. 如何高效开启你的顾问人生模式
  10. 三角函数$y=Asin(\omega x+\phi)$的图像和性质