题意
给出一个n个数的序列和区间长度k,让你输出每个长度为k区间内的最大值和最小值,顺序是从左往右。
解题思路
这是单调队列的题,但看了这个题的时间12000ms,感觉能用BST搞一搞。交了一发TLE,后来看到discuss里面有人说BST要用C++提交,然后原封不动的用C++提交,过了。而且很莫名其妙,我用输入外挂比我不用输入外挂慢了接近2000ms。。。
代码
/*
_ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
佛祖保佑 永无BUG
*/
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e6+5;
const int inf = 0x3f3f3f3f;
struct node
{
int minn,maxx;
} arr[maxn<<2];
void pushup(int rt)
{
arr[rt].minn=min(arr[rt<<1].minn,arr[rt<<1|1].minn);
arr[rt].maxx=max(arr[rt<<1].maxx,arr[rt<<1|1].maxx);
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&arr[rt].minn);
arr[rt].maxx=arr[rt].minn;
return;
}
int m=l+r>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
pushup(rt);
}
int querymin(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return arr[rt].minn;
int m=l+r>>1,ans=inf;
if(L<=m) ans=min(ans,querymin(L,R,l,m,rt<<1));
if(R> m) ans=min(ans,querymin(L,R,m+1,r,rt<<1|1));
return ans;
}
int querymax(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return arr[rt].maxx;
int m=l+r>>1,ans=-inf;
if(L<=m) ans=max(ans,querymax(L,R,l,m,rt<<1));
if(R> m) ans=max(ans,querymax(L,R,m+1,r,rt<<1|1));
return ans;
}
int main()
{
#ifdef DEBUG
freopen("in.txt","r",stdin);
#endif // DEBUG
int n,k;
scanf("%d%d",&n,&k);
build(1,n,1);
for(int i=1; i<n-k+2; i++)
printf("%s%d",i==1?"":" ",querymin(i,i+k-1,1,n,1));
printf("\n");
for(int i=1; i<n-k+2; i++)
printf("%s%d",i==1?"":" ",querymax(i,i+k-1,1,n,1));
printf("\n");
return 0;
}