题解:SP32899 MEANARR - Mean of array
前言
又到了喜闻乐见的 SPOJ 水题解大时间,蒟蒻翻了整整三天,终于翻到了这道在蒟蒻水平范围内的题目,于是光速发了题解,吐槽一下本题基本什么也没有,从数据范围到标签全部都是未补全的情况。
题目大意
给定一个有
分析
首先肯定是给出满足条件区间的式子(下面的公式中用
进一步化为:
发现其中的
即
于是问题转化为:给定一个长为
这是一个明显的二维偏序问题,考虑用树状数组求解。
实现
根据分析中提到的方法,将每个元素都减去
代码
下面给出代码,注意需要开 long long,且注意对前缀和数组进行离散化后再存点。
#include <bits/stdc++.h>
#define ll long long
#define copy ada
#define int long long
#define lowbit(x) x&-x
#define rsort(a) sort(a+1,a+n+1),reverse(a+1,a+n+1)
#define IOS ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
using namespace std;
const int N=7e5+10;
int n,k,a[N],sum[N],ans,copy[N],m;
struct b1t{//树状数组
int c[N];
void add(int x,int val){
for(;x<=n;x+=lowbit(x)){
c[x]+=val;
}
}
int q(int x){
int ret=0;
for(;x;x-=lowbit(x)){
ret+=c[x];
}
return ret;
}
}tr;
int get_rank(int x){
return lower_bound(copy+1,copy+m+1,x)-copy;
}
signed main() {
IOS
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]-=k;
sum[i]=sum[i-1]+a[i];
copy[i]=sum[i];
if(sum[i]>=0)ans++;
}
sort(copy+1,copy+n+1);//离散化
m=unique(copy+1,copy+n+1)-(copy+1);
for(int i=1;i<=n;i++){
int rank=get_rank(sum[i]);
ans+=tr.q(rank);//统计答案
tr.add(rank,1);//加点
}
cout<<ans;
return 0;
}