思路:
树状数组+离散化
条件可转化为
,即
,这就转化为一个类似二维偏序的东西。
的取值范围
,即对每一个
都查找这个范围里的
大于
的个数有多少个。
建立树状数组,从左到右将
依次插入到树状数组中,插入之前首先对未查出状态进行查找,将合法个数加入答案。
注意
的范围是
,
,要提前插入到树状数组中。
因为
数组较大,我们首先将其离散化。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
ll c[maxn];
int lowbit(int x){
return x&(-x);
}
void add(int x,int d){
while(x<=200005){
c[x]+=d;x+=lowbit(x);
}
}
ll sum(int x){
ll ans=0;
while(x>0){
ans+=c[x];x-=lowbit(x);
}
return ans;
}
int n;
ll t,a[maxn],pre[maxn],lsh[maxn];
int main(){
scanf("%d%lld",&n,&t);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
pre[i]=pre[i-1]+a[i];
lsh[i]=pre[i];
}
lsh[n+1]=0;
sort(lsh+1,lsh+1+n+1);
int m=unique(lsh+1,lsh+1+n+1)-lsh-1;
int tmp=lower_bound(lsh+1,lsh+1+n+1,0)-lsh;
add(tmp,1);
ll ans=0;
for(int i=1;i<=n;i++){
int k=upper_bound(lsh+1,lsh+1+n+1,pre[i]-t)-lsh;
ans+=i-sum(k-1);
k=lower_bound(lsh+1,lsh+1+n+1,pre[i])-lsh;
add(k,1);
}
printf("%lld\n",ans);
}