分析:大于等于m的变成1,否则变成0,预处理前缀和,枚举起点,找到第一个点前缀和大于m即可
找第一个点可以二分可以尺取
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; const int N = 2e5+5; int T,n,m,k,a[N],sum[N]; int main(){ scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;++i){ scanf("%d",&a[i]); if(a[i]>=m)a[i]=1; else a[i]=0; } for(int i=1;i<=n;++i)sum[i]=sum[i-1]+a[i]; LL ret=0; for(int i=1;i<=n;++i){ if(n-i+1<k)break; if(sum[n]-sum[i-1]<k)break; int l=i+k-1,r=n; while(l<r){ int mid=(l+r)>>1; if(sum[mid]-sum[i-1]>=k)r=mid; else l=mid+1; } int tmp=(l+r)>>1; ret+=(n-tmp+1); } printf("%I64d ",ret); } return 0; }