题意:维护一个序列,支持区间同加或同乘一个数、询问区间和。
(x+d)*c=x*c+d*c标记就是这样处理的,剩下的就是注意到处取模了。
#include<cstdio> #include<cstring> #include<iostream> #define LL long long using namespace std; const int maxn=100010; struct node{ int L,R; LL sum; LL plu,mul; } tree[maxn<<2]; int a[maxn],mod,n,m; void pushup(int p){ tree[p].sum=(tree[p<<1].sum+tree[p<<1|1].sum)%mod; } void update1(int p,LL d){ int len=tree[p].R-tree[p].L+1; tree[p].sum=(tree[p].sum+d*len%mod)%mod; tree[p].plu=(tree[p].plu+d)%mod; } void update2(int p,LL d){ tree[p].sum=(tree[p].sum*d)%mod; tree[p].plu=(tree[p].plu*d)%mod; tree[p].mul=(tree[p].mul*d)%mod; } void pushdown(int p){ update2(p<<1,tree[p].mul); update2(p<<1|1,tree[p].mul); tree[p].mul=1; update1(p<<1,tree[p].plu); update1(p<<1|1,tree[p].plu); tree[p].plu=0; } void build(int p,int L,int R){ if(L==R){ tree[p].L=tree[p].R=L; tree[p].sum=a[L]; tree[p].plu=0; tree[p].mul=1; return; } int mid=L+R>>1; build(p<<1,L,mid); build(p<<1|1,mid+1,R); tree[p].L=L; tree[p].R=R; tree[p].mul=1; tree[p].plu=0; pushup(p); } void add(int p,int L,int R,int d){ int n_L=tree[p].L; int n_R=tree[p].R; if(L<=n_L && n_R<=R){ update1(p,d); return; } pushdown(p); int mid=n_L+n_R>>1; if(L<=mid)add(p<<1,L,R,d); if(mid<R)add(p<<1|1,L,R,d); pushup(p); } void mul(int p,int L,int R,int d){ int n_L=tree[p].L; int n_R=tree[p].R; if(L<=n_L && n_R<=R){ update2(p,d); return; } pushdown(p); int mid=n_L+n_R>>1; if(L<=mid)mul(p<<1,L,R,d); if(mid<R)mul(p<<1|1,L,R,d); pushup(p); } int sum(int p,int L,int R){ int n_L=tree[p].L; int n_R=tree[p].R; if(L<=n_L && n_R<=R)return tree[p].sum; pushdown(p); int mid=n_L+n_R>>1; LL ret=0; if(L<=mid)ret=(ret+sum(p<<1,L,R))%mod; if(mid<R) ret=(ret+sum(p<<1|1,L,R))%mod; return ret; } int main(){ scanf("%d%d",&n,&mod); for(int i=1;i<=n;i++)scanf("%d",&a[i]); build(1,1,n); scanf("%d",&m); for(int i=1;i<=m;i++){ int fg,L,R,d; scanf("%d",&fg); switch(fg){ case 1:{ scanf("%d%d%d",&L,&R,&d); mul(1,L,R,d); break; } case 2:{ scanf("%d%d%d",&L,&R,&d); add(1,L,R,d); break; } case 3:{ scanf("%d%d",&L,&R); printf("%d\n",sum(1,L,R)); break; } } } }