luogu2717

luogu2717

他们共有 n 项寒假作业。zzy 给每项寒假作业都定义了一个疲劳值 \(a_i\),表示抄这个作业所要花的精力。

zzs 现在想要知道,有多少组连续的寒假作业的疲劳值的平均值不小于 k?

简单地说,给定一个长度为 n 的正整数序列 {\(a_i\)},求出有多少个连续子序列的平均值不小于 k。


好久没有写程序了,新学期继续!写个简单的,开个头!
这个算是cdq吧!实际就是一个归并排序!当然事要各个数减k,然后前缀和。


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,k;
int sz[maxn],f[maxn];
int as[maxn];
void cdq(int l,int r)
{
	if(l==r)return;
	int mid=(l+r)>>1;
	cdq(l,mid);
	cdq(mid+1,r);
	int q=l,h=mid+1,pp=l;
	int cnt=0;
	while(q<=mid&&h<=r)
	{
		if(sz[q]<=sz[h])
		{
			++cnt;
			f[pp]=sz[q];
			++q;++pp;
		}
		else
		{
			as[h]+=cnt;
			f[pp]=sz[h];
			++pp;++h;
		}
	}
	while(q<=mid)
	{
		++cnt;
		f[pp]=sz[q];
		++q;++pp;
	}
	while(h<=r)
	{
		as[h]+=cnt;
		f[pp]=sz[h];
		++pp;++h;
	}
	for(int i=l;i<=r;++i)sz[i]=f[i];
}
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",sz+i);
		sz[i]-=k;
		sz[i]+=sz[i-1];
	}
	cdq(0,n);
	long long ans=0;
	for(int i=1;i<=n;++i)ans+=as[i];
	cout<<ans<<endl;
	return 0;
}

posted on 2022-02-15 09:31  gryzy  阅读(34)  评论(0编辑  收藏  举报

导航