码迷,mamicode.com
首页 > 其他好文 > 详细

自用综合线段树模板(区间加乘、区间置数、区间求和)

时间:2020-05-17 16:08:05      阅读:38      评论:0      收藏:0      [点我收藏+]

标签:自用   max   ==   求和   style   code   uil   down   int   

ll p,a[MAXN],atag[MAXN],mtag[MAXN],ctag[MAXN],tree[MAXN];

void Pushup(int rt){tree[rt]=(tree[rt<<1]+tree[rt<<1|1])%p;}

void Pushdown(int rt,int ln,int rn){
    if(ctag[rt]!=-1){
        ctag[rt<<1]=ctag[rt<<1|1]=ctag[rt];
        tree[rt<<1]=ctag[rt]*ln%p;
        tree[rt<<1|1]=ctag[rt]*rn%p;
        atag[rt<<1]=atag[rt<<1|1]=0;
        mtag[rt<<1]=mtag[rt<<1|1]=1;
        ctag[rt]=-1;
    }
    if(mtag[rt]!=1){
        mtag[rt<<1]=(mtag[rt<<1]*mtag[rt])%p;
        mtag[rt<<1|1]=(mtag[rt<<1|1]*mtag[rt])%p;
        atag[rt<<1]=(atag[rt<<1]*mtag[rt])%p;
        atag[rt<<1|1]=(atag[rt<<1|1]*mtag[rt])%p;
        tree[rt<<1]=(tree[rt<<1]*mtag[rt])%p;
        tree[rt<<1|1]=(tree[rt<<1|1]*mtag[rt])%p;
        mtag[rt]=1;
    }
    if(atag[rt]){
        atag[rt<<1]=(atag[rt<<1]+atag[rt])%p;
        atag[rt<<1|1]=(atag[rt<<1|1]+atag[rt])%p;
        tree[rt<<1]=(tree[rt<<1]+atag[rt]*ln)%p;
        tree[rt<<1|1]=(tree[rt<<1|1]+atag[rt]*rn)%p;
        atag[rt]=0;
    }
}

void Build(int l,int r,int rt){
    atag[rt]=0; ctag[rt]=-1; mtag[rt]=1;
    if(l==r){
        tree[rt]=a[l]%p;
        return ;
    }
    int mid=(l+r)/2;
    Build(ls);
    Build(rs);
    Pushup(rt);
}

void Add(int L,int R,int C,int l,int r,int rt){
    if(L<=l&&R>=r){
        tree[rt]=(tree[rt]+1ll*C*(r-l+1))%p;
        atag[rt]=(atag[rt]+C)%p;
        return ;
    }
    int mid=(l+r)/2;
    Pushdown(rt,mid-l+1,r-mid);
    if(L<=mid)Add(L,R,C,ls);
    if(R>mid)Add(L,R,C,rs);
    Pushup(rt);
}

void Mul(int L,int R,int C,int l,int r,int rt){
    if(L<=l&&R>=r){
        tree[rt]=tree[rt]*C%p;
        atag[rt]=atag[rt]*C%p;
        mtag[rt]=mtag[rt]*C%p;
        return ;
    }
    int mid=(l+r)/2;
    Pushdown(rt,mid-l+1,r-mid);
    if(L<=mid)Mul(L,R,C,ls);
    if(R>mid)Mul(L,R,C,rs);
    Pushup(rt);
}


void Change(int L,int R,int C,int l,int r,int rt){
    if(L<=l&&R>=r){
        tree[rt]=1ll*(r-l+1)*C%p;
        ctag[rt]=C%p;
        atag[rt]=0;
        mtag[rt]=1;
        return ;
    }
    int mid=(l+r)/2;
    Pushdown(rt,mid-l+1,r-mid);
    if(L<=mid)Change(L,R,C,ls);
    if(R>mid)Change(L,R,C,rs);
    Pushup(rt);
}

ll Query(int L,int R,int l,int r,int rt){
    if(L<=l&&R>=r)return tree[rt]%p;
    int mid=(l+r)/2;
    Pushdown(rt,mid-l+1,r-mid);
    ll ans=0;
    if(L<=mid)ans=(ans+Query(L,R,ls))%p;
    if(R>mid)ans=(ans+Query(L,R,rs))%p;
    return ans;
}

 

自用综合线段树模板(区间加乘、区间置数、区间求和)

标签:自用   max   ==   求和   style   code   uil   down   int   

原文地址:https://www.cnblogs.com/Mmasker/p/12905461.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!