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;
}