权值线段树模版

struct seg_T{
    int t[N],sz;

    inline void pushup(int x){
        t[x]=t[x<<1]+t[x<<1|1];
    }

    void change(int x,int l,int r,int val,int s){//加数修改都用ta
        int mid=(l+r)>>1;
        if(l==r){t[x]+=s,sz+=s;return;}
        if(val<=mid) change(x<<1,l,mid,val,s);
        else change(x<<1|1,mid+1,r,val,s);
        pushup(x);
    }

    int queryK(int x,int l,int r,int rk){//查第K大
        int mid=(l+r)>>1;
        if(l==r) return l;
        if(t[x<<1]>=rk) return queryK(x<<1,l,mid,rk);
        else return queryK(x<<1|1,mid+1,r,rk-t[x<<1]);
    }

    int query(int x,int l,int r,int ql,int qr){//区间数次
        int mid=(l+r)>>1,ans=0;
        if(ql<=l&&qr>=r) return t[x];
        if(ql<=mid) ans+=query(x<<1,l,mid,ql,qr);
        if(qr>mid) ans+=query(x<<1|1,mid+1,r,ql,qr);
        return ans;
    }

    inline int rank(int x){//查排名
        if(x<=1) return 1;
        return query(1,1,sz,1,x-1)+1;
    }

    int find_pre(int x,int l,int r){
        int mid=(l+r)>>1;
        if(l==r) return l;
        if(t[x<<1|1]) return find_pre(x<<1|1,mid+1,r);
        else return find_pre(x<<1,l,mid);
    }

    inline int pre(int x,int l,int r,int val){//查前驱
        int mid=(l+r)>>1,ans=0;
        if(r<val){
            if(t[x]) return find_pre(x,l,r);
            return 0;
        }
        if(mid<val-1&&t[x<<1|1]&&(ans=pre(x<<1|1,mid+1,r,val))) return ans;
        else return pre(x<<1,l,mid,val);
    }

    int find_next(int x,int l,int r){
        int mid=(l+r)>>1;
        if(l==r) return l;
        if(t[x<<1]) return find_next(x<<1,l,mid);
        else return find_next(x<<1|1,mid+1,r);
    }

    inline int next(int x,int l,int r,int val){//查后缀
        int mid=(l+r)>>1,ans=0;
        if(val<l){
            if(t[x]) return find_next(x,l,r);
            return 0;
        }
        if(val<mid&&t[x<<1]&&(ans=next(x<<1,l,mid,val))) return ans;
        else return next(x<<1|1,mid+1,r,val);
    }
}p;

//あの一等星のさんざめく光で
posted @ 2021-04-10 20:55  wsy_jim  阅读(54)  评论(0编辑  收藏  举报