HDU5806 NanoApe Loves Sequence Ⅱ(尺取法\two pointers)
鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5806
題目
Time Limit:2000MS Memory Limit:131072KB
Description
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
Now he wants to know the number of continous subsequences of the sequence in such a manner that the
Note : The length of the subsequence must be no less than
Input
The first line of the input contains an integer
In each test case, the first line of the input contains three integers
The second line of the input contains
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,m,k,並給你一個長度爲n的數列。讓你求他們的最大連續子序列個數,要求連續子序列要滿足數列中第k大的數大於等於m。
分析
題目數據範圍較大,使用暴力枚舉一定會TLE。
使用尺取法(two pointers)來做即可,核心思想是記錄前綴和。 其次,對於
後注:如果數據不是很強,可以用樹狀數組水過。但是寫了一發樹狀數組T了,看來數據的確非常強。
源碼
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
#include<sstream>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<utility>
#include<sstream>
#define mem0(x) memset(x,0,sizeof x)
#define mem1(x) memset(x,-1,sizeof x)
#define dbug cout<<"here"<<endl;
//#define LOCAL
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 200010;
const int MOD = 1000000007;
int s[MAXN];
int main(){
//two pointers 尺取法
#ifdef LOCAL
freopen("C:\\Users\\asus-z\\Desktop\\input.txt","r",stdin);
freopen("C:\\Users\\asus-z\\Desktop\\output.txt","w",stdout);
#endif
int t;
ll tmp;
scanf("%d", &t);
while(t--){
ll n,m,k;
mem0(s);
scanf("%I64d%I64d%I64d", &n, &m, &k);
for(int i = 1; i <= n; ++i){
scanf("%I64d", &tmp);
s[i] = s[i-1];
if(tmp >= m)
s[i]++;
}
ll l, r, cnt;
l = 0;
r = k;
cnt = 0;
while(r <= n){
while(s[r]-s[l] >= k)
l++;
cnt += l;
r++;
}
printf("%I64d\n", cnt);
}
return 0;
}