1215 数组的宽度

Posted SJY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1215 数组的宽度相关的知识,希望对你有一定的参考价值。

题目来源: Javaman
基准时间限制:1 秒 空间限制:131072 KB 分值: 80
技术分享 收藏
技术分享 关注
N个整数组成的数组,定义子数组a[i]..a[j]的宽度为:max(a[i]..a[j]) - min(a[i]..a[j]),求所有子数组的宽度和。
Input
第1行:1个数N,表示数组的长度。(1 <= N <= 50000)
第2 - N + 1行:每行1个数,表示数组中的元素(1 <= A[i] <= 50000)
Output
输出所有子数组的宽度和。
Input示例
5
1
2
3
4
5
Output示例
20
思路:单调栈;
我们只要统计每个数做为最小的数和最大的数所在区间有多少个。这样求当前数作为最大的数左右范围,这个用单调栈维护下,同理最小的也是
然后左区间大小乘右区间大小就是这个数作为最大的出现的区间数;
以1 5 4 2 3为例,逐个入栈计算每个数的右边界:
1入栈 => 1
5入栈,前面所有比5小的出栈,并将右边界设为5 => 5 (确定了1的右边界是5,对应下标为1)
4入栈,前面所有比4小的出栈,并将右边界设为4 => 5 4
2入栈,前面所有比2小的出栈,并将右边界设为2 => 5 4 2
3入栈,前面所有比3小的出栈,并将右边界设为3 => 5 4 3(确定了2的右边界是3,对应下标为4)
最后所有数出栈,将5 4 3这3个数的右边界的下标设为5。
 
这样可以确认,每个数字最多进一次栈出一次栈,所有复杂度是O(n)的。
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string.h>
  5 #include<math.h>
  6 #include<stack>
  7 #include<set>
  8 #include<queue>
  9 using namespace std;
 10 typedef long long LL;
 11 typedef struct node
 12 {
 13         int x;
 14         int id;
 15 } ss;
 16 LL ans[60000];
 17 int ll[60000];
 18 int rr[60000];
 19 stack<ss>stcx;
 20 int main(void)
 21 {
 22         int n,m;
 23         while(scanf("%d",&n)!=EOF)
 24         {
 25                 int i,j;
 26                 LL sum = 0;
 27                 for(i = 1; i <= n; i++)
 28                 {
 29                         scanf("%lld",&ans[i]);
 30                 }
 31                 while(!stcx.empty())
 32                         stcx.pop();
 33                 for(i = 1; i  <= n; i++)
 34                 {
 35                         while(!stcx.empty())
 36                         {
 37                                 ss ad = stcx.top();
 38                                 if(ad.x >= ans[i])
 39                                 {
 40                                         ss ak;
 41                                         ll[i] = ad.id+1;
 42                                         ak.id = i;
 43                                         ak.x = ans[i];
 44                                         stcx.push(ak);
 45                                         break;
 46                                 }
 47                                 else
 48                                 {
 49                                         stcx.pop();
 50                                         rr[ad.id] = i-1;
 51                                 }
 52                         }
 53                         if(stcx.empty())
 54                         {
 55                                 ll[i] = 1;
 56                                 ss ak;
 57                                 ak.x = ans[i];
 58                                 ak.id = i;
 59                                 stcx.push(ak);
 60                         }
 61                 }
 62                 while(!stcx.empty())
 63                 {
 64                         ss ak = stcx.top();
 65                         stcx.pop();
 66                         rr[ak.id] = n;
 67                         //printf("1\n");
 68                 }
 69 
 70                 for(i = 1; i <= n; i++)
 71                 {
 72                         sum+=ans[i]*((rr[i]-i+1)*(i-ll[i]+1));
 73                 }
 74                      for(i = 1; i  <= n; i++)
 75                 {
 76                         while(!stcx.empty())
 77                         {
 78                                 ss ad = stcx.top();
 79                                 if(ad.x <=  ans[i])
 80                                 {
 81                                         ss ak;
 82                                         ll[i] = ad.id+1;
 83                                         ak.id = i;
 84                                         ak.x = ans[i];
 85                                         stcx.push(ak);
 86                                         break;
 87                                 }
 88                                 else
 89                                 {
 90                                         stcx.pop();
 91                                         rr[ad.id] = i-1;
 92                                 }
 93                         }
 94                         if(stcx.empty())
 95                         {
 96                                 ll[i] = 1;
 97                                 ss ak;
 98                                 ak.x = ans[i];
 99                                 ak.id = i;
100                                 stcx.push(ak);
101                         }
102                 }
103                 while(!stcx.empty())
104                 {
105                         ss ak = stcx.top();
106                         stcx.pop();
107                         rr[ak.id] = n;
108                 }
109                    for(i = 1; i <= n; i++)
110                 {
111                         sum-=ans[i]*((rr[i]-i+1)*(i-ll[i]+1));
112                 }
113                 printf("%lld\n",sum);
114         }
115         return 0;
116 }

 

以上是关于1215 数组的宽度的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1215 数组的宽度

51nod 1215 单调栈/迭代

51nod 1215 数组的宽度&poj 2796 Feel Good(单调栈)

$P1215 [USACO1.4]母亲的牛奶 Mother's Milk$

Android获取片段中的布局高度和宽度

如何设置 vscode 的代码片段,以便在自动完成后自动触发 vscode 的智能感知?