原题链接
NanoApe, the Retired Dog, has returned back to prepare for for the National Higher Education Entrance Examination!
In math class, NanoApe picked up sequences once again. He wrote down a sequence with n numbers and a number m on the paper.
Now he wants to know the number of continous subsequences of the sequence in such a manner that the k-th largest number in the subsequence is no less than m.
Note : The length of the subsequence must be no less than k.
Input
The first line of the input contains an integer T, denoting the number of test cases.
In each test case, the first line of the input contains three integers n,m,k.
The second line of the input contains n integers A1,A2,…,An, denoting the elements of the sequence.
1≤T≤10, 2≤n≤200000, 1≤k≤n/2, 1≤m,Ai≤109
Output
For each test case, print a line with one integer, denoting the answer.
Sample Input
1
7 4 2
4 2 7 7 6 5 1
Sample Output
18
题目描述
有n个数字的序列,要求你找出子序列长度不小于k且这个子序列中第k大的数字不小于m的数量
思路:(尺取)取出一个区间内存在 num 个数字 >= m,并且这num == k,那么无论你在往这个区间加入一个 >= m的数还是一个 < m的数都是一个满足要求的子序列,所以我们只需要计算出后面的数字个数,就可以得到这么多个子序列,然后重复上述操作
例如:样例中k = 2、m = 4,那么我们先取到2(k)个 >= m的数字,即 4 2 7,那么后面的序列无论你怎么加数字他们都可以符合要求
代码如下
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
int a[200000];
int main()
{
int i,j,t,n,k,m,num;//num用来记录尺取区间大于等于m的数字个数
long long ans;//记录满足子序列的个数
scanf("%d",&t);
while(t--)
{
scanf("%d %d %d",&n,&m,&k);
for(i = 0;i < n;i++)
scanf("%d",&a[i]);
i = j = ans = num = 0;
while(1)
{
while(j < n && num < k)
{
if(a[j++] >= m)
num++;
}
//该区间不符合条件,那么后面也就不可能了,结束循环
if(num < k)
break;
//找到了恰好满足条件的序列,那么后面的序列都满足,所以加上 n-j ,记得加1(本身序列)
if(num >= k)
ans += (n - j + 1);
//如果该区间的第一个元素大于等于m,那么num--
if(a[i] >= m)
num--;
i++;
}
printf("%lld\n",ans);
}
return 0;
}