You are given an array a consisting of n elements. The imbalance value of some subsegment of this array is the difference between the maximum and minimum element from this segment. The imbalance value of the array is the sum of imbalance valuesof all subsegments of this array.
For example, the imbalance value of array [1, 4, 1] is 9, because there are 6different subsegments of this array:
- [1] (from index 1 to index 1), imbalance value is 0;
- [1, 4] (from index 1 to index 2), imbalance value is 3;
- [1, 4, 1] (from index 1 to index 3), imbalance value is 3;
- [4] (from index 2 to index 2), imbalance value is 0;
- [4, 1] (from index 2 to index 3), imbalance value is 3;
- [1] (from index 3 to index 3), imbalance value is 0;
You have to determine the imbalance value of the array a.
Input
The first line contains one integer n (1 ≤ n ≤ 106) — size of the array a.
The second line contains n integers a1, a2... an (1 ≤ ai ≤ 106) — elements of the array.
Output
Print one integer — the imbalance value of a.
Example
Input
3 1 4 1
Output
9
题目大意:给出一个序列,要求所有子序列的最大最小值只差的绝对值之和。
解题思路:第一反应是按照贡献来算,但是没有具体的思路。正解是对于每个数利用单调栈维护每个数
为最大最小值的区间。
然后最后的答案就是ans=(以a[i]为最大值的区间个数)*a[i]-(以a[i]为最小值的区间个数)*a[i];
其中区间个数可以根据以a为最值得左右区间得出。
然后会发现连样例都过不了。。。。。
这是因为1 4 1
我们算以第一个1为最小值的时候
1 4
1 4 1
算了两次。
算最后一个1为最小值的时候也算了两次。
也就是 1 4 1 重复算了。
所以我们在我们只要让区间内没有相等的数就可以了。也就是用单调栈维护的时候让左区间为开区间。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define sca(x) scanf("%d",&x)
const int N = 1e6+5;
stack<int>s;
int L[N],R[N];
int L1[N],R1[N];
int a[N];
int main()
{
int n;
sca(n);
for(int i=1; i<=n; i++)
{
sca(a[i]);
}
for(int i=1; i<=n; i++)
{
while(s.size()>0&&a[s.top()]>a[i])s.pop();
if(s.size()==0)L[i]=1;
else L[i]=s.top()+1;
s.push(i);
}
while(!s.empty())s.pop();
for(int i=n; i>=1; i--)
{
while(s.size()>0&&a[s.top()]>=a[i])s.pop();
if(s.size()==0)R[i]=n;
else R[i]=s.top()-1;
s.push(i);
}
while(!s.empty())s.pop();
for(int i=1; i<=n; i++)
{
while(s.size()>0&&a[s.top()]<a[i])s.pop();
if(s.size()==0)L1[i]=1;
else L1[i]=s.top()+1;
s.push(i);
}
while(!s.empty())s.pop();
for(int i=n; i>=1; i--)
{
while(s.size()>0&&a[s.top()]<=a[i])s.pop();
if(s.size()==0)R1[i]=n;
else R1[i]=s.top()-1;
s.push(i);
}
LL ans=0;
for(int i=1;i<=n;i++)
{
ans+=((1LL*(i-L1[i]+1)*(R1[i]-i))+i-L1[i])*a[i];
ans-=((1LL*(i-L[i]+1)*(R[i]-i))+i-L[i])*a[i];
}
cout<<ans<<endl;
}
/*
1 4 1
1 3
2 2
1 4 1
1 2 4 1
(i-L[i])*(R[i]-i)+(R[i]-i)+(i-L[i])
*/