tag1是乘的懒标记,tag2是加的懒标记 update1,addtag1是乘的 update2,addtag2是加的
#include<bits/stdc++.h>
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
typedef long long ll ;
const int N=1e5+10;
ll n,q,m,a[N],tree[N*4],tag1[N*4],tag2[N*4];
void push_up(int x){
tree[x]=tree[ls(x)]+tree[rs(x)];
tree[x]%=m;
}
void build(ll p,ll pl,ll pr){
tag1[p]=1;
if(pl==pr){
tree[p]=a[pl];
tree[p]%=m;
return;
}
ll mid=(pl+pr)>>1;
build(ls(p),pl,mid);
build(rs(p),mid+1,pr);
push_up(p);
}
void addtag1(ll p,ll key){
tag1[p]*=key%m;
tag2[p]*=key%m;
tree[p]*=key%m;
}
void addtag2(ll p,ll pl, ll pr,ll key)
{
tag2[p]+=key;
tree[p]+=(pr-pl+1)*key;
tree[p]%=m;
}
void push_down(ll p,ll pl,ll pr){
if(tag1[p]!=1){
ll mid=(pl+pr)>>1;
addtag1(ls(p),tag1[p]);
addtag1(rs(p),tag1[p]);
tag1[p]=1;
}
if(tag2[p]){
ll mid=(pl+pr)>>1;
addtag2(ls(p),pl,mid,tag2[p]);
addtag2(rs(p),mid+1,pr,tag2[p]);
tag2[p]=0;
}
}
void update1(ll p,ll pl,ll pr,ll L,ll R,ll key){
if(L<=pl&&pr<=R){
addtag1(p,key);
return ;
}
push_down(p,pl,pr);
ll mid=(pl+pr)>>1;
if(L<=mid)update1(ls(p),pl,mid,L,R,key);
if(R>mid)update1(rs(p),mid+1,pr,L,R,key);
push_up(p);
}
void update2(ll p,ll pl,ll pr,ll L,ll R,ll key){
if(L<=pl&&pr<=R){
addtag2(p,pr,pl,key);
return ;
}
push_down(p,pl,pr);
ll mid=(pl+pr)>>1;
if(L<=mid)update2(ls(p),pl,mid,L,R,key);
if(R>mid)update2(rs(p),mid+1,pr,L,R,key);
push_up(p);
}
ll query(ll p,ll pl,ll pr,ll L,ll R){
ll ans=0;
if(L<=pl&&pr<=R){
return tree[p]%m;
}
push_down(p,pl,pr);
ll mid=(pl+pr)>>1;
if(L<=mid)ans+=query(ls(p),pl,mid,L,R),ans%=m;
if(R>mid)ans+=query(rs(p),mid+1,pr,L,R),ans%=m;
return ans%m;
}
int main()
{
cin>>n>>q>>m;
for(int i=1;i<=n;++i)cin>>a[i];
build(1,1,n);
while(q--){
int op,x,y,k;
cin>>op;
if(op==1){
cin>>x>>y>>k;
update1(1,1,n,x,y,k);
}
if(op==2){
cin>>x>>y>>k;
update2(1,1,n,x,y,k);
}
if(op==3){
cin>>x>>y;
cout<<query(1,1,n,x,y)<<endl;
}
}
}