提交时间:2024-11-03 15:15:09

运行 ID: 34129

#include<bits/stdc++.h> using namespace std; #define ing long long const int N=5e5+10; int T,n,k,a[N],lim; //单调队列求区间max、min struct MQ{int id,x;}p[N],q[N];int CNT,cnt,FR,fr; void find_max(int len){ for(int i=1;i<=n;i++){ q[++CNT]={i,a[i]};p[++cnt]={i,a[i]}; while(q[FR].id<i-len+1&&FR<=CNT)FR++; while(q[FR].x<=q[FR+1].x&&FR<CNT)FR++; while(p[fr].id<i-len+1&&fr<=cnt)fr++; while(p[fr].x>=q[fr+1].x&&fr<cnt)fr++; lim=max(lim,q[FR].x-p[fr].x); } } inline void init(){ CNT=cnt=0;FR=fr=1; for(int i=0;i<=5e5+5;i++)p[i]=q[i]={0,0}; } //c[L]:对于长度L,极差不小于lim的区间个数;d是c的差分数组 int c[N],d[N]; void slv(int len){ init(); int i=0;//双指针 for(int j=1;j<=n;j++){ while(i<=n){ i++; q[++CNT]={i,a[i]};p[++cnt]={i,a[i]}; while(q[FR].id<i-len+1&&FR<=CNT)FR++; while(q[FR].x<=q[FR+1].x&&FR<CNT)FR++; while(p[fr].id<i-len+1&&fr<=cnt)fr++; while(p[fr].x>=q[fr+1].x&&fr<cnt)fr++; //给右端点从i到n(长度从i-j+1到n-j+1)的区间加了一个对应的左端点 if(q[FR].x-p[fr].x>=lim){d[i-j+1]++;d[n-j+2]--;break;} } } for(int i=1;i<=len;i++){c[i]=c[i-1]+d[i];} int L=len;while(c[L]>=k)L--; printf("%lld %lld\n",lim,L+1); } signed main(){ scanf("%lld",&T); while(T--){ init();lim=0; scanf("%lld%lld",&n,&k); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); find_max(n-k+1); slv(n-k+1); } return 0; }