赞
踩
求前缀和,相当于对于每个i求1<=j<i,L<=s[i]-s[j]<=R的个数然后加起来,用权值线段树搞就好了
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- #include<iomanip>
- #include<ctime>
- #include<vector>
- #include<stack>
- #include<set>
- #include<bitset>
- #include<map>
- #include<queue>
- using namespace std;
- #define MAXN 100010
- #define MAXM 8000010
- #define MOD 1000000007
- #define INF 10000000000ll
- #define eps 1e-8
- #define ll long long
- int n,L,R;
- int siz[MAXM],son[MAXM][2];
- int tot;
- int rt;
- void change(int &x,ll y,ll z,ll p){
- if(!x){
- x=++tot;
- }
- siz[x]++;
- if(y==z){
- return ;
- }
- ll mid=y+z>>1;
- if(p<=mid){
- change(son[x][0],y,mid,p);
- }else if(p>mid){
- change(son[x][1],mid+1,z,p);
- }
- }
- int ask(int x,ll y,ll z,ll l,ll r){
- if(!x){
- return 0;
- }
- if(y==l&&z==r){
- return siz[x];
- }
- ll mid=y+z>>1;
- if(r<=mid){
- return ask(son[x][0],y,mid,l,r);
- }else if(l>mid){
- return ask(son[x][1],mid+1,z,l,r);
- }else{
- return ask(son[x][0],y,mid,l,mid)+ask(son[x][1],mid+1,z,mid+1,r);
- }
- }
- ll ans;
- int main(){
- int i,x;
- ll s=0;
- scanf("%d%d%d",&n,&L,&R);
- for(i=1;i<=n;i++){
- scanf("%d",&x);
- change(rt,-INF,INF,s);
- s+=x;
- ans+=ask(rt,-INF,INF,max(-INF,s-R),min(INF,s-L));
- }
- printf("%lld\n",ans);
- return 0;
- }
-
- /*
- */
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。