栈和队列
栈
什么是栈?
这还用废话,当然是一头的,往里塞往外拿的容器了呗!
它能用来干嘛?
在递归某个数群时会用到.
队列
那就是一头进另一头出了呗.
bfs 和最短路一般使用队列.
单调栈、单调队列
单调栈:
主要用于寻找最值的连续段,也就是这个数最长在哪个区间里是最大/小值.
例题:Look Up 仰望
约翰的N(1≤N≤10^5)头奶牛站成一排,奶牛i的身高是Hi(l≤Hi≤1,000,000).现在,每只奶牛都在向左看齐.对于奶牛i,如果奶牛j满足i<j且Hi<Hj,我们可以说奶牛i可以仰望奶牛j. 求出每只奶牛离她最近的仰望对象.
实现:
点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define rll rg ll
#define maxn 10000001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
rll f=0,x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,a[maxn],b[maxn];
stack<ll> s;
int main()
{
n=read(); for(rll i=1;i<=n;i++) a[i]=read();
for(rll i=n;i;i--)
{
while(!s.empty()&&a[i]>=a[s.top()]) s.pop(); if(!s.empty()) b[i]=s.top(); s.push(i);
}
for(rll i=1;i<=n;i++) write(b[i]),putn;
return 0;
}
单调队列:
主要用于寻找连续段的最值,和单调栈正好相反.
为了保证单调性,前后均可能会出队,所以一般用双端队列实现.
例题:滑动窗口
给你一个长度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表:

你的任务是找出窗口在各位置时的max value,min value.
实现:
点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define rll rg ll
#define maxn 3000001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
rll f=0,x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,k,cnt,a[maxn],ans1[maxn],ans2[maxn];
deque<ll> q1,q2;
int main()
{
n=read();k=read();
for(rll i=1;i<=n;i++)
{
a[i]=read();
while(!q1.empty()&&a[q1.back()]>=a[i]) q1.pop_back();while(!q2.empty()&&a[q2.back()]<=a[i]) q2.pop_back();
while(!q1.empty()&&q1.front()+k<=i) q1.pop_front();while(!q2.empty()&&q2.front()+k<=i) q2.pop_front();
q1.push_back(i);q2.push_back(i);if(i>=k) ans1[++cnt]=a[q1.front()],ans2[cnt]=a[q2.front()];
}
for(rll i=1;i<=cnt;i++) write(ans1[i]),put_;putn;for(rll i=1;i<=cnt;i++) write(ans2[i]),put_;
return 0;
}
--END--

浙公网安备 33010602011771号
我的博客: 𝟷𝙻𝚒𝚞
本文链接: https://www.cnblogs.com/1Liu/articles/16755745.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!