蒟蒻求助,orz
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
void read(ll& x) {
ll f = 1; x = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
x *= f;
}
ll tree[ 4*100000+5 ];//开4倍空间
struct cpp{
int v;
ll mul,add;
}flag[ 4*100000+5 ];
ll mod;
inline int ls(int p){ return p<<1; }//等价于rt*2
inline int rs(int p){ return (p<<1)|1; }//等价于rt*2+1
inline void push_up( int p ){//向上更新
tree[p]=( tree[ls(p)]+tree[rs(p)] )%mod;
}
inline void push_down( int p,int len ){//下压标记
if( flag[p].v==0 || len==1) return;
if( flag[ ls(p) ].v!=flag[ p ].v && flag[ ls(p) ].v!=0 )
push_down( ls(p),len- (len>>1) );
if( flag[ rs(p) ].v!=flag[ p ].v && flag[ rs(p) ].v!=0 )
push_down( rs(p),(len>>1) );
flag[ ls(p) ].v=flag[ rs(p) ].v=flag[ p ].v;
if( flag[p].v==1 ){
flag[ ls(p) ].mul=flag[ ls(p) ].mul*flag[ p ].mul%mod;
flag[ rs(p) ].mul=flag[ rs(p) ].mul*flag[ p ].mul%mod;
tree[ ls(p) ]=tree[ ls(p) ]*flag[p].mul%mod;
tree[ rs(p) ]=tree[ rs(p) ]*flag[p].mul%mod;
}else if( flag[p].v==2 ){
flag[ ls(p) ].add=( flag[ ls(p) ].add+flag[ p ].add )%mod;
flag[ rs(p) ].add=( flag[ rs(p) ].add+flag[ p ].add )%mod;
tree[ ls(p) ]=( tree[ ls(p) ]+( len- (len>>1) )*flag[p].add )%mod;
tree[ rs(p) ]=( tree[ rs(p) ]+(len>>1)*flag[p].add )%mod;
}
flag[p].v=0;
flag[p].mul=1;
flag[p].add=0;
}
void build( int L,int R,int p ){
flag[p].mul=1;
if(L==R){
read(tree[p]);//scanf("%lld",&tree[p]);按顺序输入即可
return;
}
int M = (L+R)>>1;
build(L,M,ls(p));
build(M+1,R,rs(p));
push_up(p);
}
void update(int L,int R,int p,int uL,int uR,ll val,int key){
if( L>=uL && R<=uR ){
if( key!=flag[p].v && flag[p].v!=0 )
push_down(p,R-L+1);
flag[p].v=key;
if( flag[p].v==1 ){
flag[p].mul=flag[p].mul*val%mod;
tree[p]=val*tree[p]%mod;
}
else{
flag[p].add=( flag[p].add+val )%mod;
tree[p]=( tree[p]+val*(R-L+1) )%mod;
}
return;
}
push_down(p,R-L+1);
int M=( L+R )>>1;
if( uL<=M ) update(L,M,ls(p),uL,uR,val,key);
if( uR>=M+1 ) update(M+1,R,rs(p),uL,uR,val,key);
push_up(p);
}
ll query(int L,int R,int p,int qL,int qR){
if( L>=qL && R<=qR ){
return tree[p];
}
push_down(p,R-L+1);
int M=(L+R)>>1;
ll ret=0;
if( qL<=M ) ret+=query(L,M,ls(p),qL,qR);
if( qR>=M+1 ) ret+=query(M+1,R,rs(p),qL,qR);
return ret%mod;
}
int n,m;
int main(){
//freopen("in.txt","r",stdin);
cin>>n>>m>>mod;
build(1,n,1);
ll op,x,y,k;
while(m--){
read(op);
if(op==1){
read(x);read(y);read(k);
//cin>>x>>y>>k;
update(1,n,1,x,y,k%mod,1);
}else if(op==2){
read(x);read(y);read(k);
//cin>>x>>y>>k;
update(1,n,1,x,y,k%mod,2);
}else{
read(x);read(y);
//cin>>x>>y;
cout<<query(1,n,1,x,y)<<endl;
}
}
return 0;
}