数列求和

单调栈:

首先求子序列的最大值最小值之差,将最大值和最小值开两个单调栈维护即可

 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 }

 

posted @ 2017-07-13 20:58  Z-Y-Y-S  阅读(200)  评论(0编辑  收藏  举报