题意:
给你n个数和一个k
把n分成连续的n-k+1个区间
第一行按顺序输出每一个区间的最小值,第二行是最大值。
思路:
单调队列的模板题,这里注意的是插入队尾的时候须要二分加速
代码:
#include"stdio.h" #include"algorithm" #include"string.h" #include"iostream" #include"queue" #include"map" #include"vector" #include"string" #include"cmath" using namespace std; #define N 2222222 struct node { int x,s; }; int cmp(node a,node b) { return a.s<b.s; } int cmp1(node a,node b) { return a.s>b.s; } node q[N],v[N]; int finde_max(int l,int r,int k) { int ans=-1; while(l<=r) { int mid=(l+r)/2; if(q[mid].s>k) { ans=mid; l=mid+1; } else r=mid-1; } return ans; } int finde_min(int l,int r,int k) { int ans=-1; while(l<=r) { int mid=(l+r)/2; if(q[mid].s<k) { ans=mid; l=mid+1; } else r=mid-1; } return ans; } int main() { int n,k; while(scanf("%d%d",&n,&k)!=-1) { for(int i=1; i<=n; i++) { scanf("%d",&v[i].s); v[i].x=i; } int head=0,ed=0; for(int i=1;i<=k;i++) q[ed++]=v[i]; sort(q,q+k,cmp); for(int i=k; i<=n; i++) { if(head>ed) q[++ed]=v[i]; //入队 else { int tep=finde_min(head,ed,v[i].s); if(tep==-1) q[ed=head]=v[i]; else q[ed=tep+1]=v[i]; } while(q[head].x+k<=i) head++; //出队 printf(i==n?"%d ":"%d ",q[head].s); } head=0,ed=0; for(int i=1;i<=k;i++) q[ed++]=v[i]; sort(q,q+k,cmp1); for(int i=k; i<=n; i++) { if(head>ed) q[++ed]=v[i]; //入队 else { int tep=finde_max(head,ed,v[i].s); if(tep==-1) q[ed=head]=v[i]; else q[ed=tep+1]=v[i]; } while(q[head].x+k<=i) head++; //出队 printf(i==n?"%d ":"%d ",q[head].s); } } return 0; }