线段树 区间乘,加,求和
对于此类问题,维护时要先乘后加,不管是对于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);
}