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
151 2 3 4 5
Sample output
Case 1: 35
In fact, it is to find the number of Intervals Based on the maximum number of I and the number of Intervals Based on the minimum number of I. The monotonous stack idea can be used, and poj2559 is almost a question. Is used to find the range that can be extended from left to right with the nth value of I.
#include <iostream>#include <cstdio>using namespace std;typedef __int64 LL;const int maxn = 100000+10;int t, n;LL l[maxn], r[maxn], a[maxn];LL solve(){ LL ans = (LL)(n+1)*n/2; l[1] = 1; for(int i = 2; i <= n; i++) { int tmp = i; while(tmp > 1 && a[tmp-1] >= a[i]) tmp = l[tmp-1]; l[i] = tmp; } r[n] = n; for(int i = n-1; i > 0; i--) { int tmp = i; while(tmp < n && a[tmp+1] > a[i]) tmp = r[tmp+1]; r[i] = tmp; } for(int i = 1; i <= n; i++) ans -= a[i] * (LL)(i - l[i] + 1) * (LL)(r[i] - i + 1); l[1] = 1; for(int i = 2; i <= n; i++) { int tmp = i; while(tmp > 1 && a[tmp-1] <= a[i]) tmp = l[tmp-1]; l[i] = tmp; } r[n] = n; for(int i = n-1; i > 0; i--) { int tmp = i; while(tmp < n && a[tmp+1] < a[i]) tmp = r[tmp+1]; r[i] = tmp; } for(int i = 1; i <= n; i++) ans += a[i] * (LL)(i - l[i] + 1) * (LL)(r[i] - i + 1); return ans;}int main(){ cin >> t; for(int ca = 1; ca <= t; ca++) { cin >> n; for(int i = 1; i < n+1; i++) scanf("%I64d", &a[i]); printf("Case %d: %I64d\n", ca, solve()); } return 0;}
Zookeeper
2014 Xiangtan Invitational competition C question: xiangda OJ 1205 range (monotonous stack)