Codeforces Round #510 (Div. 2)--D. Petya and Array--(红黑树或动态线段树)

版权声明: https://blog.csdn.net/qq_40791842/article/details/82780345

                                          D. Petya and Array

                                                                                time limit per test:2 seconds

                                                                        memory limit per test:256 megabytes

                                                                                    input:standard input

                                                                                  output:standard output

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−1

题意:给定一个数组,问有多少个不同的区间[l,r] (l<=r)使得区间和小于给定的数t.

解法:维护前缀和sum[i],则以i为r的区间个数为所有满足sum[i]-sum[j]<t的j的个数(j<=i).该式变形为-sum[j]<t-sum[i],所以可以用一颗红黑树维护-sum[j](点击查看红黑树的库实现博客),然后用order_of_key查询t-sum[i]的rank,这个rank其实就是右端点为i时左端点满足的个数。总复杂度nlog(n).其中遍历数组为o(n),红黑树查询为log(n).

注:由于红黑树里不能有相同元素,所以这里让红黑树维护pair<-sum[i],index>,其中index为下标i.这样就能保证能存储相同的-sum[i].看红黑树实现起来多简短!

代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<bitset>
#include<stack>
#include<set>
#include<queue>
#include<map>
#include<cmath>
#include<string>
#include<cstring>
#include<ctime>
#include<fstream>
#include<cstdlib>
#include<algorithm>
#include<ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

#define pii pair<int, int>
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define per(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i>=b;i--)
#define all(x) x.begin(),x.end()
#define PER(i,x) for(auto i=x.begin();i!=x.end();i++)
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef tree<pair<ll,int>,null_type,less< pair<ll,int> >,rb_tree_tag,tree_order_statistics_node_update> rbtree;
const double eps=1.0e-5;
const int maxn=200000+10;

int n;
ll tmp,t,sum=0,ans=0;

int main()
{
	//freopen("C:\\Users\\MAC\\Desktop\\in.txt","r",stdin);
	rbtree it;
	scanf("%d%lld",&n,&t);
	it.insert(make_pair(0,0));
	per(i,1,n){
		scanf("%lld",&tmp);
		sum+=tmp;
		ans+=it.order_of_key(pair<ll,int>(t-sum,0));
		it.insert(pair<ll,int>(-sum,i));
	}
	printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/qq_40791842/article/details/82780345
今日推荐