这题调了一晚上快调死了= =
此题看着很奇怪,我们先搞一搞式子看看它到底要我们求什么
大概是 ∑ni=1 [L <= Σkj=i a_i <= R] (k >= i)
发现这可以转成前缀和的形式
就是 ∑ni=1 [L <= s[k] - s[j] <= R] (i <= j <= k)
发现它就是求对于每一个 s[k] 满足 s[j] ∈ [s[k] - R, s[k] - L] 的 s[j] 个数
可以权值线段树区间求和搞啊!
然后就是一个裸的线段树了
二分和离散化总容易出一些奇怪的小锅
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cstdio>
#define lson (x << 1)
#define rson ((x << 1) | 1)
using namespace std;
typedef long long ll;
const int MAXN = 100005;
struct Node{
ll sum;
}t[(MAXN * 3) << 2];
int n, sizb, rnk[MAXN];
ll lll, rrr, res;
ll num[MAXN], uni[MAXN * 3];
inline void pushup(int x) {
t[x].sum = t[lson].sum + t[rson].sum;
return;
}
void update(int dst, int l, int r, int x) {
if(l == r) {
++t[x].sum;
return;
}
int mid = ((l + r) >> 1);
if(dst <= mid) update(dst, l, mid, lson);
else update(dst, mid + 1, r, rson);
pushup(x);
return;
}
ll query(int L, int R, int l, int r, int x) {
if(L > R) return 0ll;
if(L <= l && r <= R) {
return t[x].sum;
}
int mid = ((l + r) >> 1);
ll ans = 0ll;
if(L <= mid) ans = query(L, R, l, mid, lson);
if(mid < R) ans += query(L, R, mid + 1, r, rson);
return ans;
}
inline int lower(int l, int r, ll val, ll *arr) {
register int mid;
while(l < r) {
mid = ((l + r) >> 1);
if(arr[mid] >= val) r = mid;
else l = mid + 1;
}
return l;
}
inline int upper(int l, int r, ll val, ll *arr) {
register int mid;
while(l < r) {
mid = ((l + r + 1) >> 1);
if(arr[mid] <= val) l = mid;
else r = mid - 1;
}
return l;
}
int main() {
scanf("%d%lld%lld", &n, &lll, &rrr);
uni[++sizb] = 0ll;
register ll pres = 0ll;
for(int i = 1; i <= n; ++i) {
scanf("%lld", &num[i]);
pres += num[i];
uni[++sizb] = pres;
uni[++sizb] = pres - rrr;
uni[++sizb] = pres - lll;
}
sort(uni + 1, uni + sizb + 1);
sizb = unique(uni + 1, uni + sizb + 1) - uni - 1;
pres = 0ll;
for(int i = 1; i <= n; ++i) {
pres += num[i];
rnk[i] = lower_bound(uni + 1, uni + sizb + 1, pres) - uni;
}
update(lower_bound(uni + 1, uni + sizb + 1, 0) - uni, 1, sizb, 1);
pres = 0ll;
for(int i = 1; i <= n; ++i) {
pres += num[i];
int lef = lower(1, sizb, pres - rrr, uni), rig = upper(1, sizb, pres - lll, uni);
res += query(lef, rig, 1, sizb, 1);
update(rnk[i], 1, sizb, 1);
}
printf("%lld\n", res);
return 0;
}