思路
机智题,自创双指针发同向扫描。
将不小于mm的数看作1,剩下的数看作0,那么只要区间内1的个数不小于k则可行,枚举左端点,右端点可以通过two-pointer求出。
时间复杂度O(n)。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include <stdio.h> #include <iostream> #include <cmath> #include <stdlib.h> #include <cstring> using namespace std; #define ll long long ll a[200005],m,k,n; bool b[200005]; int main(){ int T; for(cin>>T;T--;){ memset(b,0,sizeof(b)); scanf("%I64d%I64d%I64d",&n,&m,&k); for(int i=1; i<= n ;i++){ scanf("%I64d",&a[i]); if(a[i]>=m)b[i]=1; } ll i=1,j=k,cnt=0; ll ans=0; for(int i=1; i<=k ; i++) if(b[i])cnt++; while(j<=n){ while(cnt<k && j<=n){ if(b[++j])cnt++; } ans+=n-j+1; if(b[i])cnt--; i++; } printf("%I64d\n",ans); } return 0; }
|