肥婆纳妾 @ 2019-09-09 18:11:29
#include<iostream>
#include<cstdio>
#include<math.h>
#include<climits>
using namespace std;
#define FOR(i,v,n) for(register int i=v;i<=n;++i)
#define CLEAR_ARR(a,val) memset(a,val,sizeof(a))
#define _MAX(a,b) (a>b?a:b)
#define _MIN(a,b) (a>b?b:a)
const int maxn=1e7+6;
int bsz,n,m;
int tag_min[10000],tag_max[10000],bl[maxn],v[maxn];
inline int read(){
int x=0,w=0;char ch=0;
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return w?-x:x;
}
void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void build(){
bsz=sqrt(n*10);
FOR(i,0,1000)tag_max[i]=INT_MIN,tag_min[i]=INT_MAX;
FOR(i,1,n)v[i]=read();
FOR(i,1,n)bl[i]=(i-1)/bsz+1;
FOR(i,1,n)tag_min[bl[i]]=_MIN(tag_min[bl[i]],v[i]),tag_max[bl[i]]=_MAX(tag_max[bl[i]],v[i]);
}
inline int ask_min(int l,int r){
if(l<1)l=1;
if(r<1)return 0;
int ans=INT_MAX;
FOR(i,l,_MIN(bl[l]*bsz,r))
ans=_MIN(ans,v[i]);
if(bl[l]!=bl[r])
FOR(i,(bl[r]-1)*bsz+1,r)
ans=_MIN(ans,v[i]);
FOR(i,bl[l]+1,bl[r]-1)
ans=_MIN(ans,tag_min[i]);
return ans;
}
inline int ask_max(int l,int r){
if(l<1)l=1;
if(r<1)return 0;
int ans=INT_MIN;
FOR(i,l,_MIN(bl[l]*bsz,r))
ans=_MAX(ans,v[i]);
if(bl[l]!=bl[r])
FOR(i,(bl[r]-1)*bsz+1,r)
ans=_MAX(ans,v[i]);
FOR(i,bl[l]+1,bl[r]-1)
ans=_MAX(ans,tag_max[i]);
return ans;
}
int main(){
n=read(),m=read();
build();
FOR(i,m+1,n+1)
write(ask_min(i-m,i-1)),putchar(' ');
putchar('\n');
FOR(i,m+1,n+1)
write(ask_max(i-m,i-1)),putchar(' ');
return 0;
}
by GreenDay @ 2019-09-09 18:16:48
线段树/单调队列呀
by 肥婆纳妾 @ 2019-09-09 18:19:49
@GreenDay 不会算复杂度,就想试一下,结果t了一个点