标签:
权值线段树。
要求 L<=(s[i]-s[j])<=R (i<j)。 的i和j的数量。
所以把前缀和s加入一棵权值线段树,每次询问满足条件的范围中的权值的个数。
权值线段树不能像普通线段树一样预处理,否则因为权值范围过大会爆掉。
#include<cstdio> #include<algorithm> #include<cstring> #define LL long long using namespace std; const LL inf = 10000000000ll; const int maxn = 100000 + 10; const int maxm = 8000000 + 10; struct segtree { LL l[maxm],r[maxm]; int lc[maxm],rc[maxm]; int v[maxm],vid; void change(int &x,LL L,LL R,LL p) { if(!x) {x=++vid;l[x]=L;r[x]=R;} v[x]++; if(L==R) return; LL mid=(L+R)>>1; if(p<=mid) change(lc[x],L,mid,p); else change(rc[x],mid+1,R,p); } int ask(int x,LL L,LL R) { if(!x) return 0; if(r[x]<L || l[x]>R) return 0; if(L<=l[x]&&r[x]<=R) return v[x]; return ask(lc[x],L,R)+ask(rc[x],L,R); } }seg; int root; LL res=0,n,L,R; int main() { LL s=0; scanf("%lld%lld%lld",&n,&L,&R); for(int i=1,x;i<=n;i++) { scanf("%d",&x); seg.change(root,-inf,inf,s); s+=x; res+=seg.ask(root,max(-inf,s-R),min(inf,s-L)); } printf("%lld\n",res); return 0; }
标签:
原文地址:http://www.cnblogs.com/invoid/p/5660913.html