分块

2017-09-18  本文已影响0人  fo0Old

分块

struct Block
{
    static const int __=50005;
    static const int _b_=300;
    ll a[__];int n,bsz,bel[__];
    ll ad[_b_];
    vector<ll>ord[_b_];

    ll operator[](int x){return a[x]+ad[bel[x]];}

    void build()
    {
        bsz=(int)sqrt(n);
        for(int i=1;i<=n;i++)
            ord[bel[i]=(i-1)/bsz+1].pb(a[i]);
        for(int i=1;i<=bel[n];i++)
            sort(ord[i].begin(),ord[i].end());
    }

    void rebuild(int x)
    {
        int r=(bel[n]==x)?n:(x*bsz);
        ord[x].clear();
        for(int i=(x-1)*bsz+1;i<=r;i++)
            ord[x].pb(a[i]);
        sort(ord[x].begin(),ord[x].end());
    }

    void add(int l,int r,ll val)
    {
        for(int i=l;i<=min(r,bel[l]*bsz);i++)
            a[i]+=val;
        rebuild(bel[l]);
        if(bel[l]==bel[r])return;
        for(int i=bel[l]+1;i<bel[r];i++)
            ad[i]+=val;
        for(int i=(bel[r]-1)*bsz+1;i<=r;i++)
            a[i]+=val;
        rebuild(bel[r]);
    }

    int get_min(int l,int r,ll val)
    {
        int res=0;
        for(int i=l;i<=min(r,bel[l]*bsz);i++)
            if(a[i]+ad[bel[i]]<val)res++;
        if(bel[l]==bel[r])return res;
        for(int i=bel[l]+1;i<bel[r];i++)
            res+=lower_bound(ord[i].begin(),ord[i].end(),val-ad[i])-ord[i].begin();
        for(int i=(bel[r]-1)*bsz+1;i<=r;i++)
            if(a[i]+ad[bel[i]]<val)res++;
        return res;
    }

    void clear(){memset(ad,0,sizeof(ad));}
}b;
上一篇下一篇

猜你喜欢

热点阅读