Bzoj4627--BeiJing2016回转寿司

维护前缀和,枚举区间起点l,则满足条件的区间结尾r必须满足L<=pre[r]-pre[l]<=R

用值域线段树维护即可

代码 :

#include<bits/stdc++.h>
#define LL long long
using namespace std;

#define MAXN 100005

const int L=0,R=1;
int n,a[MAXN],D,U;LL pre[MAXN],ans;
int sz=1,root=1;
struct Node{
    int s,son[2];
}x[MAXN*40];

void Chg(LL l,LL r,LL v,int &now,int p) {
    if(!now) now=++sz;x[now].s+=p;
    if(l==r) return;
    LL mid=l+r>>1;
    if(v>mid) Chg(mid+1,r,v,x[now].son[R],p);
    else Chg(l,mid,v,x[now].son[L],p);
}

int Query(LL l,LL r,LL ql,LL qr,int now) {
    if(ql==l&&qr==r) return x[now].s;
    LL mid=l+r>>1;
    if(ql>mid) return Query(mid+1,r,ql,qr,x[now].son[R]);
    else if(qr<=mid) return Query(l,mid,ql,qr,x[now].son[L]);
    else return Query(l,mid,ql,mid,x[now].son[L])+Query(mid+1,r,mid+1,qr,x[now].son[R]);
}

int main() {
    scanf("%d%d%d",&n,&D,&U);
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        pre[i]=pre[i-1]+a[i];
    }
    for(int i=0;i<=n;i++) {
        pre[i]+=10000000001ll;
        Chg(1,20000000002ll,pre[i],root,1);    
    }
    for(int i=0;i<n;i++) {
        Chg(1,20000000002ll,pre[i],root,-1);
        ans+=Query(1,20000000002ll,D+pre[i],U+pre[i],root);
    }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2016-10-28 10:25  ihopenot  阅读(284)  评论(0编辑  收藏  举报