感觉树状数组比较好理解,但确实非常巧妙
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
ll n,t,a[maxn],cnt[maxn],sumn[maxn];
class binary_tree
{
private:
int sumn[maxn];
int lowbit(int x){return x&(-x);}
public:
void add(int x){
for(int i=x;i<=n+1;i+=lowbit(i)) sumn[i]++;
}
ll get(int x){
ll ans=0;
for(int i=x;i;i-=lowbit(i)) ans+=sumn[i];
return ans;
}
}bit;
int main()
{
cin >> n >> t;
for(int i=2;i<=n+1;i++)//从下标2起使树状数组下标不会为0
{
cin >> a[i];
sumn[i] = sumn[i-1]+a[i];
cnt[i]=sumn[i];
}
sort(cnt+1,cnt+n+2);//为什么包括cnt[1]?因为sumn[1]什么都不选也是一种前缀
ll ans=0;
for(int i=1;i<=n+1;i++)
{
int pos = upper_bound(cnt+1,cnt+n+2,sumn[i]-t)-cnt;//第一个大的是第几名
ans+=(i-1-bit.get(pos-1));//i-1个区间,去掉不满足的get(pos-1)
pos=lower_bound(cnt+1,cnt+2+n,sumn[i]) - cnt ;//填自己原来的位置去
bit.add(pos);
}
cout<<ans;
}