VUDU

link

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;
}
posted @ 2022-07-19 15:59  Feyn618  阅读(55)  评论(0编辑  收藏  举报