数列求和
单调栈:
首先求子序列的最大值最小值之差,将最大值和最小值开两个单调栈维护即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 long long ans,cnt; 7 long long a[500001],s1[500001],s2[500001],n,tail,top; 8 int main() 9 { 10 long long i,j; 11 freopen("1.in","r",stdin); 12 freopen("1.out","w",stdout); 13 cin>>n; 14 for (i=1; i<=n; i++) 15 { 16 scanf("%lld",&a[i]); 17 } 18 tail=0; 19 top=0; 20 for (i=1; i<=n; i++) 21 { 22 while (tail&&a[s1[tail]]<a[i]) 23 { 24 cnt-=(s1[tail]-s1[tail-1])*a[s1[tail]]; 25 tail--; 26 } 27 tail++; 28 s1[tail]=i; 29 cnt+=(i-s1[tail-1])*a[i]; 30 while (top&&a[s2[top]]>a[i]) 31 { 32 cnt+=(s2[top]-s2[top-1])*a[s2[top]]; 33 top--; 34 } 35 top++; 36 s2[top]=i; 37 cnt-=(i-s2[top-1])*a[i]; 38 ans+=cnt; 39 } 40 cout<<ans; 41 }