Educational Codeforces Round 23 D. Imbalanced Array

题目连接: 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 }

猜你喜欢

转载自www.cnblogs.com/lhclqslove/p/9378870.html