rt,孩子刚会lazy-tag
#include <bits/stdc++.h>
using namespace std;
#define MAXN 100002
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
using ll=long long;
ll n,m,q;
ll tree[MAXN<<2],a[MAXN],add[MAXN<<2],mul[MAXN<<2];
void build(ll p,ll l,ll r){
if(l==r){
tree[p]=a[l]%m;
}
build(ls(p),1,(l+r)>>1);
build(rs(p),((l+r)>>1)+1,r);
tree[p]=(tree[ls(p)]+tree[rs(p)])%m;
mul[p]=1,add[p]=0;
return ;
}
inline void spread(ll p,ll l,ll r){
ll mid=(l+r)>>1;
tree[ls(p)]=(tree[ls(p)]*mul[p]+((mid-l+1)*add[p])%m)%m;
tree[rs(p)]=(tree[rs(p)]*mul[p]+((r-mid)*add[p])%m)%m;
mul[ls(p)]=(mul[ls(p)]*mul[p])%m;
mul[rs(p)]=(mul[rs(p)]*mul[p])%m;
add[ls(p)]=(add[ls(p)]*mul[p]+add[p])%m;
add[rs(p)]=(add[rs(p)]*mul[p]+add[p])%m;
mul[p]=1,add[p]=0;
return;
}
inline void update_add(ll sx,ll sy,ll l,ll r,ll k,ll p){
if(sx<=l&&r<=sy){
add[p]=(add[p]+k)%m;
tree[p]=(tree[p]+(r-l+1)*k)%m;
return ;
}
spread(p,l,r);
tree[p]=tree[ls(p)]+tree[rs(p)];
ll mid=(l+r)>>1;
if(sx<=mid) update_add(sx,sy,l,mid,k,ls(p));
if(sy>mid) update_add(sx,sy,mid+1,r,k,rs(p));
tree[p]=tree[ls(p)]+tree[rs(p)];
return ;
}
inline void update_mul(ll sx,ll sy,ll l,ll r,ll k,ll p){
if(sx<=l&&r<=sy){
add[p]=(add[p]*k)%m;
mul[p]=(mul[p]*k)%m;
tree[p]=(tree[p]*k)%m;
return ;
}
spread(p,l,r);
tree[p]=tree[ls(p)]+tree[rs(p)];
ll mid=(l+r)>>1;
if(sx<=mid) update_mul(sx,sy,l,mid,k,ls(p));
if(sy>mid) update_mul(sx,sy,mid+1,r,k,rs(p));
tree[p]=tree[ls(p)]+tree[rs(p)];
return ;
}
inline ll query(ll sx,ll sy,ll l,ll r,ll p){
if(sx<=l&&r<=sy){
return tree[p]%m;
}
spread(p,l,r);
ll res=0;
ll mid=(l+r)>>1;
if(sx<=mid) res+=query(sx,sy,l,mid,ls(p));
res%=m;
if(sy>mid) res+=query(sx,sy,mid+1,r,rs(p));
res%=m;
return res;
}
int main(){
scanf("%lld %lld %lld",&n,&q,&m);
for(int i = 1; i<=n; i++){
scanf("%lld",a+i);
}
build(1,1,n);
ll opt,x,y,k;
while (m--)
{
scanf("%lld",&opt);
switch (opt)
{
case 1:
scanf("%lld %lld %lld",&x,&y,&k);
update_mul(x,y,1,n,k,1);
break;
case 2:
scanf("%lld %lle %lld",&x,&y,&k);
update_add(x,y,1,n,k,1);
case 3:
scanf("%lld",&x,&y);
printf("%lld\n",query(x,y,1,n,1));
default:
break;
}
}
return 0;
}