比赛 |
Segment Tree Competition |
评测结果 |
AAAAAAAAA |
题目名称 |
滑动窗口 |
最终得分 |
100 |
用户昵称 |
_Itachi |
运行时间 |
1.335 s |
代码语言 |
C++ |
内存使用 |
2.75 MiB |
提交时间 |
2016-08-28 19:03:21 |
显示代码纯文本
#include<cstdio>
#include<string>
#include<cstring>
#include<deque>
#include<iostream>
#define maxn 1000005
using namespace std;
int a[maxn];
int main(){
freopen("window.in","r",stdin);
freopen("window.out","w",stdout);
int k,n,x,y,f,b;
deque<int>h,l;
scanf("%d%d",&n,&k);
if(k>n)k=n;//鲁棒性,如果区间比数量大,把数量赋值给区间
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
h.push_front(1);
l.push_front(1);//把第一个进去 ,因为只有一个,必是最大和最小
for(int i=2;i<=k;i++){
while(y=h.back(),a[y]<=a[i]){
h.pop_back();
if(h.empty())break;
}//因为1一开始入队 ,所以一定非空
//将队尾比自己小或相等的去掉(以为自己后过期,当自己过期时 ,一定删掉的早已过期,无法继承)
h.push_back(i);//将自己进去,因为自己可能继承
while(x=l.back(),a[x]>=a[i]){
l.pop_back();
if(l.empty())break;
}//因为1一开始入队 ,所以一定非空
//将队尾比自己大的或相等的去掉(以为自己后过期,当自己过期时 ,一定删掉的早已过期,无法继承)
l.push_back(i);//将自己进去,因为自己可能继承
}//把前k个压进去
printf("%d ",a[l.front()]);//输出第一个区间最小值
for(int i=k+1;i<=n;i++){
b=l.front();//检查队首是否过期
if(b==i-k)l.pop_front();//因为队后的一定比队首晚入,所以只需判断队首
if(l.empty())l.push_front(i);//如果队空了,直接压进去
else {
while(x=l.back(),a[x]>=a[i]){
l.pop_back();
if(l.empty())break;
}//将队尾比自己大的或相等的去掉(以为自己后过期,当自己过期时 ,一定删掉的早已过期,无法继承)
l.push_back(i);//把自己加进去
}
printf("%d ",a[l.front()]);//输出区间最小值
}//处理最小值
printf("\n%d ",a[h.front()]);//输出第一个区间最大值
for(int i=k+1;i<=n;i++){
f=h.front();//检查队首是否过期
if(f==i-k)h.pop_front();//因为队后的一定比队首晚入,所以只需判断队首
if(h.empty())h.push_front(i);//如果队空了,直接压进去
else {
while(y=h.back(),a[y]<=a[i]){
h.pop_back();
if(h.empty())break;
}//将队尾比自己小或相等的去掉(以为自己后过期,当自己过期时 ,一定删掉的早已过期,无法继承)
h.push_back(i);//把自己加进去
}
printf("%d ",a[h.front()]);//输出区间最大值
}//处理最大值
}