滑动窗口
洛谷P1886 滑动窗口
这个题与P1440 求m区间内的最小值很像,只要在这个题
基础上再另维护一个递减的单调队列就好了.
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 2147483647 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(int i=a;i<=b;++i) using namespace std; int n,m; int a[2000001],q[2000001]; int top,tai; void in(int &x){ int y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(int x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } signed main(){ in(n);in(m); For(i,1,n) in(a[i]); For(i,1,n){ while(q[tai]-q[top]>=m||top==0 ) top++; o(a[q[top]]),p(' '); while(top<=tai&&a[q[tai]]>=a[i]) tai--; q[++tai]=i; } return 0; }
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <vector> #include <cstring> #define inf 2147483647 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<=b;++i) //by war //2020.3.18 using namespace std; long long n,k; long long a[N],q[N],b[N],s[N],Q[N]; long long l,r; long long L,R; void in(long long &x){ long long y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(long long x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } signed main() { in(n);in(k); For(i,1,n) in(a[i]); For(i,1,k){ while(q[r]-q[l]>=k ) l++; while(l<=r&&a[q[r]]>=a[i]) r--; q[++r]=i; while(Q[R]-Q[L]>=k ) L++; while(L<=R&&a[Q[R]]<=a[i]) R--; Q[++R]=i; } For(i,k+1,n+1){ while(q[r]-q[l]>=k) l++; s[i]=a[q[l]]; while(l<=r&&a[q[r]]>=a[i]) r--; q[++r]=i; while(Q[R]-Q[L]>=k) L++; b[i]=a[Q[L]]; while(L<=R&&a[Q[R]]<=a[i]) R--; Q[++R]=i; } For(i,k+1,n+1) o(s[i]),p(' ');p('\n'); For(i,k+1,n+1) o(b[i]),p(' ');p('\n'); return 0; }