单调栈与单调队列练习题
前导知识
:
1. 【模板】单调栈
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 3e6 + 5;
int n;
int st[N],top,a[N],ans[N];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=n;i>=1;i--){
while(top && a[st[top]]<=a[i]) --top;
ans[i]=st[top];
st[++top]=i;
}
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
return 0;
}
2. HISTOGRA - Largest Rectangle in a Histogram
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
const int N = 1e5 + 5;
int n;
int a[N];
int main(){
while(1){
cin>>n;
if(n==0) break;
for(int i=0;i<n;i++){
cin>>a[i];
}
int ans=0;
stack<int> s;
for(int i=0;i<=n;i++){
if(s.empty()||a[s.top()]<a[i])
s.push(i);
else{
int t=s.top();
s.pop();
int area=a[t]*(s.empty()?i:i-s.top()-1);
if(area > ans)
ans=area;
--i;
}
}
cout<<ans<<endl;
}
return 0;
}
3. 滑动窗口/【模板】单调队列
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define maxn 1000100
using namespace std;
int q[maxn]; /* q数组用于存序号 */
int a[maxn]; /* 用于存放原数组 */
int n,k;
void getmin(){
int head=0,tail=0;
for(int i=1;i<k;i++){
while(head<=tail && a[q[tail]]>=a[i]) tail--;
q[++tail]=i;
}
/* 先处理前两个数 */
for(int i=k;i<=n;i++){
while(head<=tail && a[q[tail]]>=a[i]) tail--;
q[++tail]=i;
while(q[head]<=i-k) head++;
printf("%d ",a[q[head]]);
}
}
void getmax(){
int head=0,tail=0;
for(int i=1;i<k;i++){
while(head<=tail && a[q[tail]]<=a[i]) tail--;
q[++tail]=i;
}
for(int i=k;i<=n;i++){
while(head<=tail && a[q[tail]]<=a[i]) tail--;
q[++tail]=i;
while(q[head]<=i-k) head++;
printf("%d ",a[q[head]]);
}
}
int main(){
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
getmin();
printf("\n");
getmax();
printf("\n");
return 0;
}