线段树维护sum值并记录add与mult用于标记下传+乘法结合律
1 #include <cstdio> 2 #define ll long long 3 inline int read() 4 { 5 register int k=0,f=1;register char c=getchar(); 6 while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 7 while (c>='0'&&c<='9')k=k*10+c-'0',c=getchar(); 8 return k*f; 9 } 10 struct node{int l,r;ll delta,sum,mult;}tree[8*(100000+10)]; 11 ll m,P; 12 inline void pushup(int cur){tree[cur].sum=(tree[cur<<1].sum+tree[cur<<1|1].sum)%P;} 13 inline void pushdown(int cur) 14 { 15 tree[cur<<1].delta=(tree[cur<<1].delta*tree[cur].mult+tree[cur].delta)%P; 16 tree[cur<<1|1].delta=(tree[cur<<1|1].delta*tree[cur].mult+tree[cur].delta)%P; 17 tree[cur<<1].sum=(tree[cur<<1].sum*tree[cur].mult+tree[cur].delta*(tree[cur<<1].r-tree[cur<<1].l+1))%P; 18 tree[cur<<1|1].sum=(tree[cur<<1|1].sum*tree[cur].mult+tree[cur].delta*(tree[cur<<1|1].r-tree[cur<<1|1].l+1))%P; 19 tree[cur<<1].mult=tree[cur<<1].mult*tree[cur].mult%P; 20 tree[cur<<1|1].mult=tree[cur<<1|1].mult*tree[cur].mult%P; 21 tree[cur].mult=1;tree[cur].delta=0; 22 } 23 ll query(int l,int r,int cur) 24 { 25 if (l<=tree[cur].l&&tree[cur].r<=r)return tree[cur].sum%P; 26 register int mid=(tree[cur].l+tree[cur].r)>>1;register ll tmp=0; 27 pushdown(cur); 28 if (l<=mid)tmp=query(l,r,cur<<1); 29 if (r>mid)tmp+=query(l,r,cur<<1|1); 30 pushup(cur); 31 return tmp; 32 } 33 void update(int l,int r,ll add,ll mul,int cur) 34 { 35 if (l<=tree[cur].l&&tree[cur].r<=r) 36 { 37 tree[cur].sum=(tree[cur].sum*mul+add*(tree[cur].r-tree[cur].l+1))%P; 38 tree[cur].delta=tree[cur].delta*mul%P; 39 tree[cur].mult=tree[cur].mult*mul%P; 40 tree[cur].delta=(tree[cur].delta+add)%P; 41 return; 42 } 43 register int mid=(tree[cur].l+tree[cur].r)>>1; 44 pushdown(cur); 45 if (l<=mid)update(l,r,add,mul,cur<<1); 46 if (r>mid)update(l,r,add,mul,cur<<1|1); 47 pushup(cur); 48 } 49 int build(int l,int r,int cur) 50 { 51 if ((tree[cur].l=l)==(tree[cur].r=r))return tree[cur].sum=read()%P; 52 build(l,(l+r)>>1,cur<<1); 53 build(((l+r)>>1)+1,r,cur<<1|1); 54 pushup(cur); 55 tree[cur].mult=1; 56 } 57 int main() 58 { 59 register int tmp,t,g,c,n=read();P=read(); 60 build(1,n,1); 61 m=read(); 62 for (register int i=1;i<=m;i++) 63 if ((tmp=read())==1)t=read(),g=read(),c=read(),update(t,g,0,c%P,1); 64 else if (tmp==2)t=read(),g=read(),c=read(),update(t,g,c%P,1,1); 65 else t=read(),g=read(),printf("%lld ",query(t,g,1)%P); 66 }