高级线段树模板(加法 + 乘法 模板)(面向对象)

template<class Info , class Tag> struct LazySegmentTree{
    int n;
    vector<Info> info;
    vector<Tag> tag;
    LazySegmentTree(vector<int>init){
         n = init.size();
         info.assign(n<<2,Info());
         tag.assign(n<<2,Tag());
         function<void(int ,int ,int)>build =[&](int p,int l,int r){
            info[p].l = l;info[p].r = r;
            if (l==r){
                info[p].x = init [l-1];
                info[p].xx = init [l-1] * init[l-1];
                return;
            }
            int mid =l+r>>1;
            build(p<<1,l,mid);
            build(p<<1|1,mid+1,r);
            pull(p);
         };
         build(1,1,n);
    }
    void pull(int p){
        info[p] =info[p<<1] + info[p<<1|1];
    }
    void apply(int p,const Tag&v){
        info[p].apply(v);
        tag[p].apply(v);
    }
    void push(int p){
        apply(p<<1,tag[p]);
        apply(p<<1|1,tag[p]);
        tag[p] = Tag();
    }
    void rangeApply(int p,int l,int r,int x,int y,const Tag&v){
        if(l >y || r< x)return;
        if(l>=x&&r<=y){
            apply(p,v);return;
        }

        push(p);
        int mid= l+r>>1;
        rangeApply(p<<1,l,mid,x,y,v);
        rangeApply(p<<1|1,mid+1,r,x,y,v);
        pull(p);
    }
    void rangeApply(int l,int r,const Tag&v){
        return rangeApply(1,1,n,l,r,v);
    }
    Info rangeQuery(int p,int l,int r,int x,int y){
        if(l>y || r<x)return Info();
        if(l >=x && r <=y)return info[p];
        push(p);
        int mid = l + r >>1;
        return rangeQuery(p<<1,l,mid,x,y) + rangeQuery(p<<1|1,mid+1,r,x,y);
    }
    Info rangeQuery(int l,int r){
        return rangeQuery(1,1,n,l,r);
    }
};
struct Tag{
    int add,mul;
    Tag(int add=0,int mul=1){
        this->add=add;
        this->mul=mul;
    }
    void apply(const Tag&t){
        add = add*t.mul;
        mul = mul*t.mul;
        add += t.add;
    }
};
struct Info{
    int l,r;
    int x,xx;
    Info(int xx=0,int x=0,int l=0,int r=0){
        this ->x =x;
        this ->xx =xx;
        this ->l =l;
        this ->r =r;
    }
    void apply(const Tag&t){
        xx = t.mul * t.mul * xx + 2*t.mul*t.add*x + (r-l+1)*t.add*t.add;
        x = t.mul * x + t.add * (r -l +1);
    }
};
Info operator + (const Info &a,const Info &b){
    return Info(a.xx+b.xx,a.x+b.x,a.l,b.r);
}

posted @ 2025-08-05 18:24  Marinaco  阅读(11)  评论(0)    收藏  举报
//雪花飘落效果