n个元素的数组,大小为k的窗口。
求窗口右滑时,窗口中的最大最小值。
#include <iostream>
#include <cstdio>
#include <deque>
#include <vector>
using namespace std;
struct pr{
int num,pos;
};
int n,k;
deque<pr> dq1,dq2;//需要出队入队,所以
const int maxn = 1e6 + 5;
int v1[maxn],v2[maxn];
void seg_max(int t,int i)
{
while (!dq1.empty() && dq1.front().pos <= i - k) {//先判断队首元素是否失效,是的话,先出队
dq1.pop_front();
}
if(dq1.empty()) dq1.push_back(pr{t,i});//从队尾入队新的元素
else{
while(!dq1.empty() && dq1.back().num < t){//单调递减队列,区间最大值 //该处可以二分找
dq1.pop_back();
}
dq1.push_back(pr{t,i});
}
v1[i] = dq1.front().num;
}
void seg_min(int t,int i)
{
while (!dq2.empty() && dq2.front().pos <= i - k) {
dq2.pop_front();
}
if(dq2.empty()) dq2.push_back(pr{t,i});
else{
while (!dq2.empty() && dq2.back().num > t) {
dq2.pop_back();
}
dq2.push_back(pr{t,i});
}
v2[i] = dq2.front().num;
}
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0' | ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void Out(int aa)
{
if(aa < 0){putchar('-');aa = -aa;}
if(aa>9)
Out(aa/10);
putchar(aa%10+'0');
}
int main()
{
n = read();k= read();
int t;
for (int i = 0; i < n; i ++) {
t = read();
seg_max(t, i);
seg_min(t,i);
}
for (int i = k - 1; i < n; i ++) {
Out(v2[i]);
if(i == n - 1) putchar('\n');
else putchar(' ');
}
for (int i = k - 1; i < n; i ++) {
Out(v1[i]);
if(i == n - 1) putchar('\n');
else putchar(' ');
}
return 0;
}