【分治计数|单调栈】51Nod 1215 数组的宽度
来源:互联网 发布:包就业java 培训班 编辑:程序博客网 时间:2024/05/23 01:18
题面在这里
用单调栈分别维护
显然很好做
其实分治的话就更简单了
只需要记录
分类讨论一下,这是分治计数的核心
示例程序:
分治计数:
#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline int red(){ int res=0,f=1;char ch=nc(); while (ch<'0'||'9'<ch) {if (ch=='-') f=-f;ch=nc();} while ('0'<=ch&&ch<='9') res=res*10+ch-48,ch=nc(); return res*f;}const int maxn=50005,INF=0x3f3f3f3f;int n,a[maxn],mx[maxn],mn[maxn];LL ans,smx[maxn],smn[maxn];void divide(int L,int R){ if (L==R) return; int mid=L+R>>1; divide(L,mid);divide(mid+1,R); mx[mid]=0;mn[mid]=INF; smx[mid]=smn[mid]=0; for (int i=mid+1;i<=R;i++){ mx[i]=max(mx[i-1],a[i]);mn[i]=min(mn[i-1],a[i]); smx[i]=smx[i-1]+mx[i];smn[i]=smn[i-1]+mn[i]; } LL Max=0,Min=INF; for (int i=mid,jx=mid,jm=mid;i>=L;i--){ Max=max(Max,(LL)a[i]);Min=min(Min,(LL)a[i]); while (jx<R&&mx[jx+1]<=Max) jx++; while (jm<R&&mn[jm+1]>=Min) jm++; ans+=Max*(jx-mid)+smx[R]-smx[jx]-Min*(jm-mid)-smn[R]+smn[jm]; }}int main(){ n=red(); for (int i=1;i<=n;i++) a[i]=red(); divide(1,n); printf("%lld",ans); return 0;}
单调栈:
#include<cstdio>#include<algorithm>#define LL long longusing namespace std;const int maxn=50005;int n,a[maxn],stk[maxn],len;LL l[maxn];int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); len=0;LL ans=0; for (int i=1;i<=n;i++){ while (len&&a[stk[len]]<=a[i]) ans+=l[stk[len]]*(i-stk[len])*a[stk[len]],len--; l[i]=i-stk[len];stk[++len]=i; } while (len) ans+=l[stk[len]]*(n-stk[len]+1)*a[stk[len]],len--; for (int i=1;i<=n;i++){ while (len&&a[stk[len]]>=a[i]) ans-=l[stk[len]]*(i-stk[len])*a[stk[len]],len--; l[i]=i-stk[len];stk[++len]=i; } while (len) ans-=l[stk[len]]*(n-stk[len]+1)*a[stk[len]],len--; printf("%lld",ans); return 0;}
阅读全文
1 0
- 【分治计数|单调栈】51Nod 1215 数组的宽度
- [分治 || 单调栈 单调队列] 51Nod 1215 数组的宽度
- 51nod 1215:数组的宽度 单调栈
- 51 Nod 1215 数组的宽度(单调栈)
- 51nod-1215 数组的宽度(单调栈)
- 【单调栈 or 分治】51Nod1215[数组的宽度]题解
- 51nod1215数组的宽度(单调栈)
- 51nod1215数组的宽度(单调栈)
- 单调栈 51nod 1962 区间计数
- 51nod 1215 数组的宽度
- 51Nod-1215-数组的宽度
- [分治] 51nod 算法马拉松25 C. 区间计数
- 51nod 1617 奇偶数组 分治
- 51nod 1102 单调栈
- 51nod 1102 【单调栈】
- 51Nod - 1102 单调栈
- 51nod 1102单调栈
- 51nod 1102 面积最大的矩形【单调栈、预处理】
- 20170921表单标签
- [BZOJ]4953: [Wf2017]Posterize DP
- poj 3728 The merchant
- 使用zTree插件实现可拖拽的树
- 数据结构与算法(9)---Java语言实现:希尔排序
- 【分治计数|单调栈】51Nod 1215 数组的宽度
- 二分查找及STL
- UVa 12216 表达式树,map(不会)
- HD-27-水池数目(搜索)
- minnowboard 安装ubuntu16.04系统
- pgsql查询统计每天的数据
- 第一篇占个坑
- Java深度历险(二)——Java类的加载、链接和初始化
- Unity_制作Loading场景进度条_效果实现