牛客 Neat Tree (单调栈)

https://ac.nowcoder.com/acm/problem/15815

首先暴力枚举每一个区间必定是超时的。那么考虑每个点对于答案的贡献值,可以这样想,对于点h[i]作为最大值在多少个区间出现,作为最小值在多少个区间出现?这个点对于答案的贡献就是h[i]*作为最大值出现的次数 - h[i]*作为最小值出现的次数,对于每个点,求一下贡献累加即可。

求每个点贡献的过程用单调栈来维护,拿求最大值的次数来举例。对于点i,找到左端第一个比h[i]大的数,记其位置为L,找到右端第一个比h[i]大的数,记其位置为R,则在(L,R)区间内包含点[i]的子区间个数就是 (i-L+1)*(R-i+1),可以画图理解一下。那么对于答案的贡献就是h[i]*(i-L+1)*(R-i+1)。

同理求出最小值的贡献,减去这个贡献,最终得到答案

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e6+5;
 5 int h[maxn],l[maxn],r[maxn],n;
 6 void solve(){
 7     ll sum = 0;
 8     stack<int> stk;
 9     for(int i = 1;i<=n;i++) cin>>h[i];
10     //先求h[i]作为一段区间的最小值出现的次数
11     for(int i = 1;i<=n;i++) {
12         while(!stk.empty() && h[stk.top()]>=h[i]) stk.pop();
13         if(stk.empty()) l[i] = 1;
14         else l[i] = stk.top() + 1;//记录h[i]左端第一个比h[i]小的index;
15         stk.push(i);//压入栈中
16     }
17     while(!stk.empty()) stk.pop();
18     for(int i = n;i>=1;i--){
19         while(!stk.empty() && h[stk.top()]>h[i]) stk.pop();
20         if(stk.empty()) r[i] = n;
21         else r[i] = stk.top()-1;//记录h[i]右端第一个比h[i]小的index;
22         stk.push(i);
23     }
24     while(!stk.empty()) stk.pop();
25     //
26     for(int i = 1;i<=n;i++) sum-=1ll*h[i]*(i-l[i]+1)*(r[i]-i+1);
27     //再求h[i]作为一段区间的最小值出现的次数
28     for(int i = 1;i<=n;i++){
29         while(!stk.empty() && h[stk.top()]<=h[i]) stk.pop();
30         if(stk.empty()) l[i] = 1;
31         else l[i] = stk.top() + 1;//记录h[i]左端第一个比h[i]大的数的index;
32         stk.push(i);
33     }
34     while(!stk.empty()) stk.pop();
35     for(int i = n;i>=1;i--){
36         while(!stk.empty() && h[stk.top()]<h[i]) stk.pop();
37         if(stk.empty()) r[i] = n;
38         else r[i] = stk.top()-1;//记录h[i]右端第一个比h[i]大的数的index;
39         stk.push(i);
40     }
41     for(int i = 1;i<=n;i++) sum+=1ll*h[i]*(i-l[i]+1)*(r[i]-i+1);
42     cout<<sum<<endl;
43 }
44 int main(){
45     while(cin>>n){
46         solve();
47     }
48     return 0;
49 }
View Code
原文地址:https://www.cnblogs.com/AaronChang/p/12437078.html