51nod 1215 数组的宽度(单调栈)
2017-10-03 20:57
393 查看
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1215
题意:
思路:
计算出以第i个数为最大值的区间范围,l_max[i]为左端点,r_max[i]为右端点,计算最小值同理可得。
计算出了区间范围,就可以计算出每个数对于答案的贡献值。
题意:
思路:
计算出以第i个数为最大值的区间范围,l_max[i]为左端点,r_max[i]为右端点,计算最小值同理可得。
计算出了区间范围,就可以计算出每个数对于答案的贡献值。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> #include<stack> #include<queue> #include<cmath> #include<map> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int INF = 0x3f3f3f3f; const int maxn = 50000+5; int n; int a[maxn]; int sta[maxn]; ll l_max[maxn],r_max[maxn]; ll l_min[maxn],r_min[maxn]; int main() { //freopen("in.txt","r",stdin); while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); int top = 0; for(int i=1;i<=n;i++) { while(top && a[sta[top]]<=a[i]) top--; if(top==0) l_max[i]=1; else l_max[i]=sta[top]+1; sta[++top]=i; } top=0; for(int i=n;i>=1;i--) { while(top && a[sta[top]]<a[i]) top--; //这儿特别注意一下 if(top==0) r_max[i]=n; else r_max[i]=sta[top]-1; sta[++top]=i; } top = 0; for(int i=1;i<=n;i++) { while(top && a[sta[top]]>=a[i]) top--; if(top==0) l_min[i]=1; else l_min[i]=sta[top]+1; sta[++top]=i; } top=0; for(int i=n;i>=1;i--) { while(top && a[sta[top]]>a[i]) top--; if(top==0) r_min[i]=n; else r_min[i]=sta[top]-1; sta[++top]=i; } ll ans =0; for(int i=1;i<=n;i++) ans+=a[i]*((i-l_max[i]+1)*(r_max[i]-i+1)-(i-l_min[i]+1)*(r_min[i]-i+1)); printf("%lld\n",ans); } return 0; }
相关文章推荐
- 51nod 1215 数组的宽度&poj 2796 Feel Good(单调栈)
- 51nod 1215 数组的宽度&poj 2796 Feel Good(单调栈)
- 51nod-1215 数组的宽度(单调栈)
- 【分治计数|单调栈】51Nod 1215 数组的宽度
- 51Nod - 1215 数组的宽度 思维+单调栈
- 51nod 1215 数组的宽度
- [分治 || 单调栈 单调队列] 51Nod 1215 数组的宽度
- 51Nod-1215-数组的宽度
- 51nod 1215:数组的宽度 单调栈
- 51nod 1215 数组的宽度
- 51 Nod 1215 数组的宽度(单调栈)
- 51nod 1215 数组的宽度
- 1215 数组的宽度
- 【单调栈 or 分治】51Nod1215[数组的宽度]题解
- 51nod1215数组的宽度(单调栈)
- 51nod 1001 数组中和等于K的数对
- 51nod 1050 循环数组最大子段和
- 51nod 1270 数组的最大代价(DP)
- 【51Nod】1001 数组中和等于K的数对
- 【51Nod】1270 - 数组的最大代价(dp)