XTUOJ 1205 Range

Range

Time Limit : 1000 MS Memory Limit : 65536 KB

Problem Description

For an array, the range function is defined below: Range(A)=Max(A)-Min(A)+1; For example, suppose A={1,2,3,4,5}, then Range(A)=5-1+1=5. Now, given an array A(length≤100000), you are going to calcalute the sum of all subarray's range. i.e sigma(i,j){Range(A[i,j])}.

Input

First line contain an integer T, there are T(1≤T≤100) cases. For each case T. The length N(1≤N≤100000), and N integers A[i](1≤A[i]≤109).

Output

Output case number first, then the answer.

Sample Input

1
5
1 2 3 4 5


Sample Output

Case 1: 35


Source

daizhenyang

解题:单调栈求出以该元素为最小元素的区间个数和以该元素为最大元素的区间个数

注意存在相同的元素的情况

 1 #include <stack>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #define pii pair<long long,long long>
 6 using namespace std;
 7 typedef long long LL;
 8 const int maxn = 100010;
 9 int d[maxn];
10 LL bgl[maxn],bgr[maxn],lel[maxn],ler[maxn];
11 stack< pii >stk;
12 int main(){
13     int T,n,cs = 1;
14     scanf("%d",&T);
15     while(T--){
16         scanf("%d",&n);
17         LL ret = (LL)n*(n+1)>>1;
18         for(int i = 0; i < n; ++i) scanf("%d",d+i);
19         memset(bgl,0,sizeof bgl);
20         memset(bgr,0,sizeof bgr);
21         memset(lel,0,sizeof lel);
22         memset(ler,0,sizeof ler);
23         while(!stk.empty()) stk.pop();
24         for(int i = 0; i < n; ++i){
25             pii now = pii(d[i],1);
26             while(!stk.empty() && stk.top().first >= d[i]){
27                 now.second += stk.top().second;
28                 stk.pop();
29             }
30             stk.push(now);
31             bgl[i] = now.second;
32         }
33         while(!stk.empty()) stk.pop();
34         for(int i = n-1; i >= 0; --i){
35             pii now = pii(d[i],1);
36             while(!stk.empty() && stk.top().first > d[i]){
37                 now.second += stk.top().second;
38                 stk.pop();
39             }
40             stk.push(now);
41             bgr[i] = now.second;
42         }
43         while(!stk.empty()) stk.pop();
44         for(int i = 0; i < n; ++i){
45             pii now = pii(d[i],1);
46             while(!stk.empty() && stk.top().first <= d[i]){
47                 now.second += stk.top().second;
48                 stk.pop();
49             }
50             stk.push(now);
51             lel[i] = now.second;
52         }
53         while(!stk.empty()) stk.pop();
54         for(int i = n-1; i >= 0; --i){
55             pii now = pii(d[i],1);
56             while(!stk.empty() && stk.top().first < d[i]){
57                 now.second += stk.top().second;
58                 stk.pop();
59             }
60             ler[i] = now.second;
61             stk.push(now);
62         }
63         for(int i = 0; i < n; ++i){
64             ret += bgl[i]*bgr[i]*-d[i];
65             ret += lel[i]*ler[i]*d[i];
66         }
67         printf("Case %d: %I64d
",cs++,ret);
68     }
69     return 0;
70 }
View Code
原文地址:https://www.cnblogs.com/crackpotisback/p/4555779.html