题意,给你一个串问你该串有几个连续子串满足该子串的第k大的数不小于m
方法,统计每个位置(包括当前位置)前面有几个大于等于m的数,一个区间只要满足 该区间 大于 m 的数有k个及以上,就是合法的
我的做法是枚举左端点,二分寻找右端点,nlogn的效率,看了别人的,用了尺取法,只要n就可以了,确实不错,自己做的时候没想到
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int num[200005];
int sum[200005];
int n, m, k;
int biSearch(int ll, int rr, int val)
{
int l = ll, r = rr;
int mid;
while (l <= r)
{
mid = (l + r) >> 1;
if (sum[mid] >= val) r = mid - 1;
else l = mid + 1;
}
return l;
}
int main(void)
{
int T;
scanf("%d", &T);
while (T--)
{
int counter = 0;
long long ans = 0;
scanf("%d%d%d", &n, &m, &k);
for (int i = 0; i < n; i++)
scanf("%d", &num[i]);
for (int i = 0; i < n; i++)
{
if (num[i] >= m)
counter++;
sum[i] = counter;
}
ans += n - biSearch(k - 1, n - 1, k);
for (int i = 1; i < n - k + 1; i++)
{
int pos = biSearch(i + k - 1, n - 1, k + sum[i - 1]);
ans += n - pos;
}
printf("%lld\n", ans);
}
return 0;
}