P3373 【模板】线段树 2
先贴个板子
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=100050;
int n,m,mod,a[N],opr,x,y,k;
inline int read(){
int cnt=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
while(isdigit(c)){cnt=(cnt<<3)+(cnt<<1)+(c^48);c=getchar();}
return cnt*f;
}
struct SEG{
int sum,mul,add,l,r;
#define sum(p) tr[p].sum
#define l(p) tr[p].l
#define r(p) tr[p].r
#define mul(p) tr[p].mul
#define add(p) tr[p].add
}tr[N<<2];
int Add(int a, int b){return a + b >= mod ? a + b - mod : a + b;}
int Mul(int a, int b){ return 1ll * a * b % mod; }
void pushup(int p){ sum(p)=Add(sum(p<<1), sum(p<<1|1));}
void build(int p,int l,int r){
l(p)=l,r(p)=r;add(p)=0;mul(p)=1;
if(l(p)==r(p)){sum(p)=a[l];mul(p)=1;return;}
int mid=(l+r)>>1;
build(p<<1,l,mid);build(p<<1|1,mid+1,r);
pushup(p);
}
void pushadd(int p, int v){
sum(p) = Add(sum(p), Mul(r(p)-l(p)+1, v));
add(p) = Add(add(p), v);
}
void pushmul(int p, int v){
sum(p) = Mul(sum(p), v);
add(p) = Mul(add(p), v);
mul(p) = Mul(mul(p), v);
}
void pushdown(int p){
if(mul(p)^1) pushmul(p<<1, mul(p)), pushmul(p<<1|1, mul(p)), mul(p) = 1;
if(add(p)) pushadd(p<<1, add(p)), pushadd(p<<1|1, add(p)), add(p) = 0;
}
void modify_add(int p,int l,int r,int d){
if(l(p)>=l&&r(p)<=r){ pushadd(p, d); return; }
pushdown(p);
int mid=(l(p)+r(p))>>1;
if(l<=mid)modify_add(p<<1,l,r,d);
if(r>mid)modify_add(p<<1|1,l,r,d);
pushup(p);
}
void modify_mult(int p,int l,int r,int d){
if(l(p)>=l&&r(p)<=r){ pushmul(p, d); return; }
pushdown(p);
int mid=(l(p)+r(p))>>1;
if(l<=mid)modify_mult(p<<1,l,r,d);
if(r>mid)modify_mult(p<<1|1,l,r,d);
pushup(p);
}
int query(int p,int l,int r){
int ans=0;
if(l(p)>=l&&r(p)<=r) return sum(p);
pushdown(p);
int mid=(l(p)+r(p))>>1;
if(l<=mid)ans=Add(ans, query(p<<1,l,r));
if(r>mid)ans=Add(ans, query(p<<1|1,l,r));
return ans;
}
void debug(int p) {
printf("%lld %lld %lld\n", sum(p), mul(p), add(p));
if (l(p) == r(p)) return;
debug(p << 1), debug(p << 1 | 1);
}
signed main(){
// freopen("1.in","r",stdin);
n=read(),m=read(),mod=read();
for(int i=1;i<=n;i++)a[i]=read();
build(1,1,n);
for(int i=1;i<=m;i++){
opr=read();
if(opr==1){x=read(),y=read(),k=read();modify_mult(1,x,y,k);}
if(opr==2){x=read(),y=read(),k=read();modify_add(1,x,y,k);}
if(opr==3){x=read(),y=read();printf("%lld\n",query(1,x,y) % mod);}
// debug(1);
// cerr<<"---------"<<endl;
// for(int j = 1; j <= n; j++) cout << query(1, j, j) << " " ;
// cout << endl;
}
return 0;
}