正题
题目链接:https://www.luogu.com.cn/problem/P5459
题目大意
nnn个数,求有多少个区间和在[L,R][L,R][L,R]范围内。
解题思路
显然我们做了前缀和之后,枚举右端点就只需要找到有多少个左端点满足在[x−R,x−L][x-R,x-L][x−R,x−L]这个范围内就好了。
将前缀和离散化之后用树状数组维护即可(也不知道这为啥是紫题)
时间复杂度O(nlogn)O(n\log n)O(nlogn)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) (x&-x)
#define ll long long
using namespace std;
const ll N=1e5+10;
ll n,L,R,cnt,t[N],a[N],b[N],ans;
void Change(ll x,ll val){while(x<=cnt){t[x]+=val;x+=lowbit(x);}return;
}
ll Ask(ll x){ll ans=0;while(x){ans+=t[x];x-=lowbit(x);}return ans;
}
int main()
{scanf("%lld%lld%lld",&n,&L,&R);for(ll i=1;i<=n;i++){scanf("%lld",&a[i]);b[++cnt]=(a[i]+=a[i-1]);}b[++cnt]=0;sort(b+1,b+1+cnt);cnt=unique(b+1,b+1+cnt)-b-1;Change(lower_bound(b+1,b+1+cnt,0)-b,1);for(ll i=1;i<=n;i++){ll l=lower_bound(b+1,b+1+cnt,a[i]-R)-b;//x-z<=R z>=x-Rll r=upper_bound(b+1,b+1+cnt,a[i]-L)-b-1;//x-z>=L z<=x-La[i]=lower_bound(b+1,b+1+cnt,a[i])-b;ans+=Ask(r)-Ask(l-1);Change(a[i],1);}printf("%lld",ans);
}