HOJ contests 15 I

版权声明:有错误欢迎大家指出。转载请注明出处~ https://blog.csdn.net/black_miracle/article/details/71566771

Beautiful Garden

Problem Description

Long long ago, there was a garden where grew N flowers. Flowers were all in a line and each had a beautiful value(integer value), say a1 a2 …aN from left to right. Remember that some flowers could be ugly so that its beautiful value could be zero or negative.

One day, someone passed by the garden and he wanted to know how many beautiful intervals there were. A interval is continuous flowers from P to Q(P <= Q), and it is beautiful if and only if Q – P + 1 >= L and aP + a(P+1) + … + aQ>= M. Can you solve this old problem?

Input

There is only one integer T(1< = T <= 100) in the first line.And then comes T test cases.

For each test case, there are three integers  N(1 <= N <= 10000), L(1 <= L <= N) and M(-100000 <= M <= 100000) in the first line, and N integers a1, a2, …, aN(-100000 <= ai<= 100000) in the second line.

Output

Print the answer in the single line for each test case.

Sample Input

3

1 1 1

1

4 2 3

1 2 3 4

扫描二维码关注公众号,回复: 4941968 查看本文章

6 3 -7

-1 -2 -3 4 -5 6

Sample Output

1

6

10


题意:给出N个数a[1],a[2]...a[N], 对于一个区间[P,Q], 若Q-P+1 >= L, 并且a[P] + a[P+1] + ... + a[Q] >= M,则区间[P,Q]为beautiful区间,
问有多少beautiful区间。


题解:离散化一下  然后for右端点  用树状数组维护左端点


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int n,m,l;
int c[10005],num[10005],cnt,a[10005],sum[10005];
void change(int pos,int x){
	while(pos<=cnt){
		c[pos]+=x;
		pos+=(pos&-pos);
	}
}
int sums(int pos){
	int ss=0;
	while(pos>0){
		ss+=c[pos];
		pos-=(pos&-pos);
	}
	return ss;
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d%d",&n,&l,&m);
		int i,j,k,ans=0;
		cnt=0;
		num[++cnt]=0;
		memset(c,0,sizeof(c)); 
		for(i=1;i<=n;i++){
			scanf("%d",&a[i]);
			sum[i]=sum[i-1]+a[i];
			num[++cnt]=sum[i];
		}
		sort(num+1,num+1+cnt);
		cnt=unique(num+1,num+1+cnt)-num-1;
		change(lower_bound(num+1,num+1+cnt,0)-num,1);
		for(i=l;i<=n;i++){
			int mr=lower_bound(num+1,num+1+cnt,sum[i]-m)-num;
			if(num[mr]!=sum[i]-m)mr--;
			ans+=sums(mr);
			change(lower_bound(num+1,num+1+cnt,sum[i-l+1])-num,1);
		}
		printf("%d\n",ans);
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/black_miracle/article/details/71566771
今日推荐