数组的宽度题解
Description
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
输出所有子数组的宽度和。
Sample Input
5 1 2 3 4 5
Sample Output
20
分析
标程
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
long long a[50005];
long long s[50005] = {0},top = 0;
int main()
{
// freopen("width.in","r",stdin);
// freopen("width.out","w",stdout);
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i++)
scanf("%d",a+i);
long long tot1 = 0,tot2 = 0;
a[0] = a[n+1] = 0;
for(int i = 1;i <= n+1;i++)
{
while(top > 0 && a[s[top]] > a[i])
{
tot1 += (s[top] - s[top-1])*(i - s[top])*a[s[top]];
top--;
}
s[++top] = i;
}
top = 0;s[0] = 0;
a[n+1] = 0x7f7f7f7f;
// cout<<tot1<<endl;
for(int i = 1;i <= n+1;i++)
{
while(top > 0 && a[s[top]] < a[i])
{
tot2 += (s[top] - s[top-1])*(i - s[top])*a[s[top]];
top--;
}
s[++top] = i;
}
cout<<tot2-tot1;
return 0;
}