Numbers of interval(前缀和数组+二分)

Numbers of interval(前缀和数组+二分)

source:河南理工大学算法协会暑期集训积分赛(二)网络同步赛 E题 点我进入评测机
单点时限: 2.0 sec

内存限制: 512 MB

描述

现在有一个数组,请计算有多少的区间 [ l , r ] ( l ≤ r ) [l, r](l≤r) [l,r](lr)满足 ∑ i = l r a i ≥ k ∑^r_{i=l} a_i ≥k i=lraik.

输入格式

第一行输入 n , k ( 1 ≤ n , k ≤ 1 0 6 ) n,k(1≤n,k≤10^6) n,k(1n,k106).
接下来输入 n n n个数,第 i i i个数为 a i ( 1 ≤ a i ≤ 1 0 3 ) a_i(1≤a_i≤10^3) ai(1ai103).

输出格式

输出满足条件的区间个数

样例
input

3 5
2 3 5

output

4

思路

看到区间问题先想到线段树和树状数组,但枚举区间太费时。
后来想到前缀和数组,然后枚举左区间,二分右区间,就可以快速找出区间个数了。

代码

#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define _for(i, a) for(ll i = 0; i < (a); i++)
#define _rep(i, a, b) for(ll i = (a); i<= (b); i++)
using namespace std;
typedef long long ll;
const ll maxn = 1000005;
const ll INF = 0x3f3f3f3f;
ll n;
ll k;
ll a[maxn];
int main() {
	scanf("%d%d", &n, &k);
	mem(a, 0);
	for (ll i = 1; i <= n; i++) {
		ll x;
		scanf("%d", &a[i]);
		a[i] += a[i - 1];
	}
	ll sum = 0;
	_rep(i, 1, n) {
		ll ans;
		ans = lower_bound(a + 1, a + n + 1, k + a[i - 1]) - a;
		if (ans != n + 1) sum += (n - ans + 1);
	}
	cout << sum << "\n";
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值