The problem of direct violence to solve the words of time complexity is certainly not, so, we want to calculate the contribution of each value, for each number of the minimum worth how many times, when the maximum worth how many times, and finally when the maximum number of times this value minus when the minimum number of times multiplied by the value of the contribution of this number, Adding the sum of the n numbers in turn is the whole difference.
When calculating the maximum value of a number, we have to understand the problem, because the interval is continuous, so, for example, if a number is the minimum value of the current interval, then he must be the smallest of the current interval (this is not nonsense), so we will find him left to go long can find how many consecutive numbers are bigger than him, Record this position, in the same way to find out how many of his right side is greater than it, so we get an interval, this interval is the minimum value of the digit, as shown can be more intuitive understanding.
Add to find the interval with a minimum of 2, then he can go to the left to find 3, up to the right can find 5, then 2 as the minimum value of the number of intervals (2+1) * (+), as follows:
[3, 9, 2], [9, 2], [2], [3, 9, 2, 5], [9, 2, 5], [2, 5]
Similarly, if 2 is the same as the maximum value, the maximum interval is only [2].
This topic also has a small trick is to preprocess each element as the most value, the leftmost to where and the right to where, you can use the known information, is the position of the previous finding to jump acceleration, so that the time complexity is not O (n^2)
Code:
#include <bits/stdc++.h>using namespacestd;Const intMAXN = 1e5 +Ten;Const intINF =0x3f3f3f3f;intA[MAXN];intL[MAXN], R[MAXN];voidPrintintL[],intN) { for(inti =1; I <= N; i++) printf ("%d", L[i]); Puts ("");}intMain () {intN; scanf ("%d", &N); for(inti =1; I <= N; i++) scanf ("%d", &A[i]); a[0] = -1, A[n +1] = -1; intSum_min =0; //The position of the element that can be extended to the left when the current element is the minimum value. for(inti =1; I <= N; i++) { if(A[i] >= a[i-1]) L[i]=i; Else { intTMP = i-1; while(A[i] <A[tmp]) { if(TMP = =l[tmp]) tmp--; Elsetmp=L[tmp]; } L[i]= tmp +1; } } //Print (L, n); //The position of the element that can be extended to the right when the current element is the minimum value. for(inti = n; I >=1; i--) { if(A[i] >= a[i +1]) R[i]=i; Else { intTMP = i +1; while(A[i] <A[tmp]) { if(TMP = =r[tmp]) tmp++; Elsetmp=R[tmp]; } R[i]= tmp-1; } } //Print (R, n); //the contribution of each element as the minimum value, and the last need to subtract for(inti =1; I <= N; i++) { intTMP = (I-l[i] +1) * (R[i]-i +1); Sum_min+ = tmp *A[i]; } a[0] = inf, A[n +1] =inf; intSum_max =0; //The position of the element that can be extended to the left when the current element is the maximum value. for(inti =1; I <= N; i++) { if(A[i] <= a[i-1]) L[i]=i; Else { intTMP = i-1; while(A[i] >A[tmp]) { if(TMP = =l[tmp]) tmp--; Elsetmp=L[tmp]; } L[i]= tmp +1; } } //Print (L, n); //The position of the element that can be extended to the right when the current element is the maximum value. for(inti = n; I >=1; i--) { if(A[i] <= a[i +1]) R[i]=i; Else { intTMP = i +1; while(A[i] >A[tmp]) { if(TMP = =r[tmp]) tmp++; Elsetmp=R[tmp]; } R[i]= tmp-1; } } //Print (R, n); //contribution of the element as the maximum value for(inti =1; I <= N; i++) { intTMP = (I-l[i] +1) * (R[i]-i +1); Sum_max+ = tmp *A[i]; } printf ("%d\n", Sum_max-sum_min); return 0;}
View Code
Sum of the difference between the maximum and minimum values of all intervals in the array (shell written questions)