题目连接: D. Imbalanced Array
题意:给你个数组,求所有子串的最大值-最小值之和
题解:对每一个位置的数,我们分别求出他作为最大值和最小值得次数在相减得到的就是答案,先考虑最大值,我们用两个数组L[],R[],L[i]表示a[i]作为最大值的左边界
R[i],表示一个大于等于a[i]的位置,L[]和R[]都可以o(n)的求出,这题可以用单调栈。最小值可以用相似的方法求出。
1 #include<bits/stdc++.h> 2 #include<set> 3 #include<cstdio> 4 #include<iomanip> 5 #include<iostream> 6 #include<string> 7 #include<cstring> 8 #include<algorithm> 9 #define pb push_back 10 #define ll long long 11 #define fi first 12 #define se second 13 #define PI 3.14159265 14 #define ls l,m,rt<<1 15 #define rs m+1,r,rt<<1|1 16 #define eps 1e-7 17 #define pii pair<int,int> 18 typedef unsigned long long ull; 19 const int mod=1e3+5; 20 const ll inf=0x3f3f3f3f3f3f3f; 21 const int maxn=1e6+5; 22 using namespace std; 23 int n,s; 24 int l[maxn],r[maxn],a[maxn]; 25 int main() 26 { 27 ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 28 cin>>n; 29 for(int i=1;i<=n;i++)cin>>a[i]; 30 for(int i=1;i<=n;i++)l[i]=r[i]=i; 31 for(int i=2;i<=n;i++) 32 { 33 int p=i; 34 while(p>1&&a[p-1]<=a[i])p=l[p-1]; 35 l[i]=p; 36 } 37 for(int i=n-1;i>=1;i--) 38 { 39 int p=i; 40 while(p<n&&a[p+1]<a[i])p=r[p+1]; 41 r[i]=p; 42 } 43 ll ans=0; 44 for(int i=1;i<=n;i++) 45 { 46 ans+=1ll*a[i]*(i-l[i]+1)*(r[i]-i+1); 47 } 48 for(int i=1;i<=n;i++)l[i]=r[i]=i; 49 for(int i=2;i<=n;i++) 50 { 51 int p=i; 52 while(p>1&&a[p-1]>=a[i])p=l[p-1]; 53 l[i]=p; 54 } 55 for(int i=n-1;i>=1;i--) 56 { 57 int p=i; 58 while(p<n&&a[p+1]>a[i])p=r[p+1]; 59 r[i]=p; 60 } 61 for(int i=1;i<=n;i++) 62 { 63 ans-=1ll*a[i]*(i-l[i]+1)*(r[i]-i+1); 64 } 65 cout<<ans<<endl; 66 return 0; 67 }