Petya has an array aa consisting of nn integers. He has learned partial sums recently, and now he can calculate the sum of elements on any segment of the array really fast. The segment is a non-empty sequence of elements standing one next to another in the array.
Now he wonders what is the number of segments in his array with the sum less than tt. Help Petya to calculate this number.
More formally, you are required to calculate the number of pairs l,rl,r (l≤rl≤r) such that al+al+1+⋯+ar−1+ar<tal+al+1+⋯+ar−1+ar<t.
Input
The first line contains two integers nn and tt (1≤n≤200000,|t|≤2⋅10141≤n≤200000,|t|≤2⋅1014).
The second line contains a sequence of integers a1,a2,…,ana1,a2,…,an (|ai|≤109|ai|≤109) — the description of Petya’s array. Note that there might be negative, zero and positive elements.
Output
Print the number of segments in Petya’s array with the sum of elements less than tt.
Examples
Input
5 4
5 -1 3 4 -1
Output
5
Input
3 0
-1 2 -3
Output
4
Input
4 -1
-2 1 -2 3
Output
3
Note
In the first example the following segments have sum less than 44:
[2,2][2,2], sum of elements is −1−1
[2,3][2,3], sum of elements is 22
[3,3][3,3], sum of elements is 33
[4,5][4,5], sum of elements is 33
[5,5][5,5], sum of elements is −1
对于这种求区间和的问题,一般会转化成前缀和的问题来求.
对于当前值sum[i]来说,要找它之后的区间和有多少个小于v,只需要找有多少个sum[k]<sum[i]+v就行,这样就转化成了某个数之后有多少个数小于一个数,这样就可以用权值线段树来解决了.因为数据很大,需要离散化一下.
代码如下:
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int maxx=4e5+100;//因为我们要把sum[i]和sum[i]+v都记录下来,所以就应该是原来数据量二倍的数据
ll sum[maxx],a[maxx],b[maxx];
struct node{
int l;
int r;
ll v;
}p[maxx<<2];
ll n,ans;
ll v;
inline void pushup(int cur)
{
p[cur].v=p[cur<<1].v+p[cur<<1|1].v;
}
inline void build(int l,int r,int cur)
{
p[cur].l=l;
p[cur].r=r;
p[cur].v=0;
if(l==r) return ;
int mid=l+r>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
}
inline void update(int pos,int cur)
{
int L=p[cur].l;
int R=p[cur].r;
if(L==R)
{
p[cur].v+=1;
return ;
}
int mid=L+R>>1;
if(pos<=mid) update(pos,cur<<1);
else update(pos,cur<<1|1);
pushup(cur);
}
inline void query(int pos,int cur)
{
int L=p[cur].l;
int R=p[cur].r;
if(L==R) return ;
int mid=L+R>>1LL;
if(pos<=mid) query(pos,cur<<1);
else
{
ans+=p[cur<<1].v;
query(pos,cur<<1|1);
}
}
int main()
{
while(~scanf("%d%lld",&n,&v))
{
int cnt=0;ans=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
b[++cnt]=sum[i];
}
if(n==1)//一的时候特判
{
if(a[1]<v) puts("1");
else puts("0");
}
else
{
for(int i=1;i<=n;i++) b[++cnt]=sum[i]+v;
sort(b+1,b+1+cnt);
int len=unique(b+1,b+1+cnt)-b-1;
build(1,len,1);
update(lower_bound(b+1,b+1+len,sum[n])-b,1);//先将最后的一个插入进去
for(int i=n-1;i>=0;i--)
{
ll x=sum[i]+v;
query(lower_bound(b+1,b+1+len,x)-b,1);//在查询的时候用的是sum[i]+v
if(i) update(lower_bound(b+1,b+1+len,sum[i])-b,1);//插入的时候用的是sum[i]
}
printf("%lld\n",ans);
}
}
return 0;
}
努力加油a啊,(o)/~