• 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
    ");
     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
    ",sum);
    114         }
    115         return 0;
    116 }
    
    
    油!油!you@
  • 相关阅读:
    mysql——前面内容——前期整理笔记00
    mysql——触发器——概念
    mysql——触发器——示例
    mysql——多表——外连接查询——左连接、右连接、复合条件查询
    mysql——多表——合并查询结果
    IT职场人生系列之七:学外语
    IT职场人生系列之十三:技术?管理?业务?
    IT职场人生系列之五:怎样面试
    IT职场人生系列之十二:语言与技术I
    IT职场人生系列之四:怎样写简历
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5930716.html
Copyright © 2020-2023  润新知