bzoj4627: [BeiJing2016]回转寿司

权值线段树。

要求 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;    
}

转载于:https://www.cnblogs.com/invoid/p/5660913.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值