栈+队列
![](https://img2022.cnblogs.com/blog/2908398/202209/2908398-20220927091148351-853170679.png)
用栈模拟表达式计算时,在表达式的开头与末尾有着表示开始与结束的标识符。所以optr栈空间应比实际用到的多一个。
单调队列:
P2216 [HAOI2007]理想的正方形 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int N=1050; int n,a,b,m[N][N]; int VER[N][N],HOR[N][N]; int ver[N][N],hor[N][N]; int main(){ scanf("%d%d%d",&a,&b,&n); for(int i=1;i<=a;i++){ for(int j=1;j<=b;j++){ scanf("%d",&m[i][j]); } } for(int i=1;i<=a;i++){ deque<int> Q,q; for(int j=1;j<=b;j++){ if(!Q.empty() && Q.front()<j-n+1)Q.pop_front(); while(!Q.empty()&&m[i][j]>m[i][Q.back()])Q.pop_back(); Q.push_back(j); if(j>n-1)HOR[i][j]=m[i][Q.front()]; if(!q.empty() && q.front()<j-n+1)q.pop_front(); while(!q.empty()&&m[i][j]<m[i][q.back()])q.pop_back(); q.push_back(j); if(j>n-1)hor[i][j]=m[i][q.front()]; } } for(int j=n;j<=b;j++){//先列后行 deque<int> q,Q; for(int i=1;i<=a;i++){ if(!Q.empty()&&Q.front()<i-n+1)Q.pop_front(); while(!Q.empty()&&HOR[i][j]>HOR[Q.back()][j])Q.pop_back(); Q.push_back(i); if(i>n-1)VER[i][j]=HOR[Q.front()][j]; if(!q.empty()&&q.front()<i-n+1)q.pop_front(); while(!q.empty()&&hor[i][j]<hor[q.back()][j])q.pop_back(); q.push_back(i); if(i>n-1)ver[i][j]=hor[q.front()][j]; } } int res=2147483647; for(int i=n;i<=a;i++){ for(int j=n;j<=b;j++){ if(VER[i][j]-ver[i][j]<res)res=VER[i][j]-ver[i][j]; } } printf("%d",res); return 0; }
单调队列模板:
#include<bits/stdc++.h> using namespace std; deque<int> q; const int N=10086; int a[N],n,m;//n个元素,队列长度m void dandiaoduilie(){ for(int i=1;i<=n;i++){ if(!q.empty() && q.front<i-m+1){ q.pop_front(); }//取出队头元素 while(!q.empty() && a[q.back]<a[i]){ q.pop_back(); }//压入新元素,老的淘汰掉 q.push_back(i); if(i>m-1)printf("%d ",q.front());//输出窗口最大值 } }