线段树 区间乘,加,求和

对于此类问题,维护时要先乘后加,不管是对于lazy下传还是将lazy加到和中。
特殊的:

void D(int rt,int l,int r,int mid){//push down
	w[L]=(w[L]*lc[rt]%M+lazy[rt]*(mid-l+1)%M)%M;
	w[R]=(w[R]*lc[rt]%M+lazy[rt]*(r-mid)%M)%M;
	lazy[L]=(lazy[L]*lc[rt]%M+lazy[rt])%M;
	lazy[R]=(lazy[R]*lc[rt]%M+lazy[rt])%M;
	(lc[L]*=lc[rt])%=M;
	(lc[R]*=lc[rt])%=M;
	lazy[rt]=0;lc[rt]=1;//前面初始化时lazy就是0,lc是1
}
void MC(int rt,int l,int r,int a,int b,int x){//维护区间乘
	if(a<=l&&r<=b){
		(lazy[rt]*=x)%=M;
		(lc[rt]*=x)%=M;
		(w[rt]*=x)%=M;
		return;
	}
	int mid=(l+r)>>1;
	D(rt,l,r,mid);
	if(a<=mid)MC(L,l,mid,a,b,x);
	if(b >mid)MC(R,mid+1,r,a,b,x);
	UP(rt);
}
posted @ 2020-07-14 20:16  liuzhaoxu  阅读(112)  评论(0编辑  收藏  举报