自用综合线段树模板(区间加乘区间置数区间求和)
Posted mmasker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自用综合线段树模板(区间加乘区间置数区间求和)相关的知识,希望对你有一定的参考价值。
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; }
以上是关于自用综合线段树模板(区间加乘区间置数区间求和)的主要内容,如果未能解决你的问题,请参考以下文章
Luogu 3373 - 模板线段树 2 - [加乘线段树]
POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)