VUDU
COCI的一大特点,卡空间。
题足够简单,每个点减去N之后求前缀和,对于每个前缀和看前面有多少前缀和小于等于它。理论上可以用动态开点线段数来做,但空间会爆只有30分左右(话说克罗地亚是穷得配不起64M以上内存的评测机吗。。。)。于是考虑优化空间,可以离线把所有前缀和离散化,再上树状数组查询和修改。
#include<bits/stdc++.h>
//#define feyn
#define int long long
const int N=1000010;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
#define lowbit (wh&-wh)
int t[N];
inline void change(int wh){
for(;wh<N;wh+=lowbit)t[wh]++;
}
inline int work(int wh){
int an=0;
for(;wh;wh-=lowbit)an+=t[wh];
return an;
}
#undef lowbit
int m,n,a[N],c[N],sum[N],cnt;
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
read(m);int ans=0;
for(int i=1;i<=m;i++)read(a[i]);
read(n);//printf("working\n");
c[++cnt]=0;
for(int i=1;i<=m;i++){
sum[i]=sum[i-1]+a[i]-n;
c[++cnt]=sum[i];
}
sort(c+1,c+cnt+1);
int num=unique(c+1,c+cnt+1)-c-1;
change(upper_bound(c+1,c+num+1,0)-c-1);
for(int i=1;i<=m;i++){
int data=upper_bound(c+1,c+num+1,sum[i])-c-1;
ans+=work(data);change(data);
}
printf("%lld",ans);
return 0;
}
一如既往,万事胜意