单调栈&单调队列入门
Posted mxang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调栈&单调队列入门相关的知识,希望对你有一定的参考价值。
此文持续更新。
啊今下午形势政策看看了
这个东西,发现我要想好好施展几何得先精通单调栈单调队列。
然后就计划刷刷水题。结果打了一晚上游戏。
又认识了一个辅助妹子,难道我的过去要被画上句号,开始一段新的恋情了吗?还记得两年前,也是那样一个普通的夜晚,也是小炮和露露,
我的小炮特别浪,总是喜欢w跳脸,但她却总是能跟上我,在我跳脸的时候击飞别人,被控的时候坩埚秒解,被追的时候预判救赎,要死的时候闪现给盾,
然而到了后来,我在说什么啊???
完蛋了啊,要被队友捅死了啊。
poj2796
定义一段区间的权值为最小值乘以区间和,求给定数组的最大权值。
找到以每个数为最小值的区间的端点。
1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 typedef long long ll; 5 const int N = 1e5+5; 6 ll n,a[N],pre[N],las[N],sum[N],q[N]; 7 int main(){ 8 scanf("%lld",&n); 9 for(int i=1;i<=n;i++)scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i]; 10 int l=0,r=0; 11 for(int i=1;i<=n;i++){ 12 while (r>0&&a[q[r]]>a[i]){ 13 las[q[r]]=i-1; 14 r--; 15 } 16 q[++r]=i; 17 } 18 while (r>0)las[q[r--]]=n; 19 for(int i=n;i>=1;i--){ 20 while (r>=0&&a[q[r]]>a[i]){ 21 pre[q[r]]=i+1; 22 r--; 23 } 24 q[++r]=i; 25 } 26 while (r>0)pre[q[r--]]=1; 27 ll ans = 0; 28 for(int i=1;i<=n;i++){ 29 if(a[i]*(sum[las[i]]-sum[pre[i]-1])>=ans) 30 ans = a[i]*(sum[las[i]]-sum[pre[i]-1]),l=pre[i],r=las[i]; 31 } 32 printf("%lld\\n%d %d",ans,l,r); 33 }
poj 3494
给01矩阵,找最大的全是1的子矩阵
枚举行,转化成直方图最大矩形面积。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 int n,m,a[2019][2019],cpp[2009][2009],q[2009],las[2009],pre[2009]; 6 int slove(int a[]){ 7 memset(las,0, sizeof(las)); 8 memset(pre,0, sizeof(pre)); 9 int l=0,r=0; 10 for(int i=1;i<=m;i++){ 11 while (r>0&&a[q[r]]>a[i]){ 12 las[q[r]]=i-1; 13 r--; 14 } 15 q[++r]=i; 16 } 17 while (r>0)las[q[r--]]=m; 18 for(int i=m;i>=1;i--){ 19 while (r>=0&&a[q[r]]>a[i]){ 20 pre[q[r]]=i+1; 21 r--; 22 } 23 q[++r]=i; 24 } 25 while (r>0)pre[q[r--]]=1; 26 int ans = 0; 27 for(int i=1;i<=n;i++)if(a[i]*(las[i]-pre[i]+1)>ans)ans = a[i]*(las[i]-pre[i]+1); 28 return ans; 29 } 30 void init(){ 31 for(int i=1;i<=m;i++){ 32 for(int l=1,r;l<=n;l=r+1){ 33 r=l; 34 if(a[l][i]==0)continue; 35 while (a[r+1][i]==1)r++; 36 for(int j=l;j<=r;j++)cpp[j][i]=r-j+1; 37 } 38 } 39 } 40 int main(){ 41 while (scanf("%d%d",&n,&m)!=EOF) { 42 memset(a,0, sizeof(a)); 43 memset(cpp,0, sizeof(cpp)); 44 for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)scanf("%d", &a[i][j]); 45 init(); 46 int ans = 0; 47 for (int i = 1; i <= n; i++) 48 ans = max(ans, slove(cpp[i])); 49 printf("%d\\n", ans); 50 } 51 }
hdu 5033
坐标轴上竖n个竿子,问你在(?,0)这个点向左向右能看到的角度范围。
单调栈处理出来每个位置向左向右能看到的竿子。
对于Xa<Xb<Xc这样的竿子来说,如果a能挡住b,那么a肯定能挡住c,所以pop(b)
询问输出是换行的。。。我一开始输出的空格给我wrong answer...坑死我了,理论1A
不memset 点的话答案会不对,,不知道为什么。
1 #include <bits/stdc++.h> 2 #define pb(x) push_back(x) 3 using namespace std; 4 typedef double db; 5 const db pi=acos(-1); 6 const int N = 2e5+5; 7 struct point { 8 db x,y; 9 bool operator <(const point &k1)const {return x<k1.x;} 10 int id; 11 }; 12 point p[N];int que[N],lef[N],rig[N];db ans[N]; 13 int T,n,cas,q,x; 14 int main(){ 15 scanf("%d",&T); 16 while (cas++<T){ 17 // memset(ans,0, sizeof(ans)); 18 // memset(que,0, sizeof(que)); 19 // memset(lef,0, sizeof(lef)); 20 // memset(rig,0, sizeof(rig)); 21 memset(p,0, sizeof(p)); 22 scanf("%d",&n); 23 for(int i=1;i<=n;i++){ 24 scanf("%lf%lf",&p[i].x,&p[i].y); 25 } 26 scanf("%d",&q); 27 for(int i=1;i<=q;i++){ 28 scanf("%lf",&p[i+n].x); 29 p[i+n].y=0;p[i+n].id=i; 30 } 31 sort(p+1,p+1+n+q); 32 int r=0; 33 for(int i=1;i<=n+q;i++){ 34 while (r>0&&p[que[r]].y<=p[i].y){ 35 r--; 36 } 37 while (r>1&&(p[que[r]].y-p[i].y)/(-p[que[r]].x+p[i].x)<=(p[que[r-1]].y-p[i].y)/(-p[que[r-1]].x+p[i].x)){ 38 r--; 39 } 40 lef[i] = que[r]; 41 que[++r] = i; 42 } 43 r=0; 44 for(int i=n+q;i>=1;i--){ 45 while (r>0&&p[que[r]].y<=p[i].y){ 46 r--; 47 } 48 while (r>1&&(p[que[r]].y-p[i].y)/(p[que[r]].x-p[i].x)<=(p[que[r-1]].y-p[i].y)/(p[que[r-1]].x-p[i].x)){ 49 r--; 50 } 51 rig[i] = que[r]; 52 que[++r] = i; 53 } 54 for(int i=1;i<=n+q;i++){ 55 if(r=p[i].id){ 56 ans[r] = atan((-p[lef[i]].x+p[i].x)/(p[lef[i]].y-p[i].y))+atan((p[rig[i]].x-p[i].x)/(p[rig[i]].y-p[i].y)); 57 ans[r] = ans[r]*180/pi; 58 } 59 } 60 printf("Case #%d\\n",cas); 61 for(int i=1;i<=q;i++){ 62 printf("%.11f\\n",ans[i]); 63 } 64 } 65 } 66 /** 67 3 68 3 69 1 2 70 2 1 71 5 1 72 1 73 4 74 */
以上是关于单调栈&单调队列入门的主要内容,如果未能解决你的问题,请参考以下文章