AC 1 3 4,其余WA,30pts
#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
long long mod;
int n;
long long a[N+5];
int q,opt;
int l,r;
long long add_num,tim_num;
struct qqq{
int L,R;
long long sum;
long long lazy_add;
long long lazy_tim;
}tree[N<<2];
void build_tree(int id,int L,int R){//建树
tree[id].L=L;
tree[id].R=R;
tree[id].lazy_add=0;
tree[id].lazy_tim=1;
if(L==R){
tree[id].sum=a[L];
return;
}
int mid=(L+R)>>1;
build_tree(id<<1,L,mid);
build_tree(id<<1|1,mid+1,R);
tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;
tree[id].sum%=mod;
return;
}
void push_down(int id){//下放lazy
if(tree[id].lazy_tim!=1){//乘法
tree[id<<1].lazy_tim*=tree[id].lazy_tim;
tree[id<<1|1].lazy_tim*=tree[id].lazy_tim;
tree[id<<1].lazy_tim%=mod;
tree[id<<1|1].lazy_tim%=mod;
tree[id].sum*=tree[id].lazy_tim;
tree[id].sum%=mod;
tree[id].lazy_tim=1;
}
if(tree[id].lazy_add!=0){//加法
tree[id<<1].lazy_add+=tree[id].lazy_add;
tree[id<<1|1].lazy_add+=tree[id].lazy_add;
tree[id<<1].lazy_add%=mod;
tree[id<<1|1].lazy_add%=mod;
tree[id].sum+=(tree[id].R-tree[id].L+1)*tree[id].lazy_add%mod;
tree[id].sum%=mod;
tree[id].lazy_add=0;
}
return;
}
void update(int id){//更新
tree[id].sum=tree[id<<1].sum*tree[id<<1].lazy_tim%mod+(tree[id<<1].R-tree[id<<1].L+1)*tree[id<<1].lazy_add%mod+tree[id<<1|1].sum*tree[id<<1|1].lazy_tim%mod+(tree[id<<1|1].R-tree[id<<1|1].L+1)*tree[id<<1|1].lazy_add%mod;
tree[id].sum%=mod;
return;
}
void change_add(int id,int L,int R,long long add){//区间加法
if(tree[id].L==L && tree[id].R==R){
tree[id].lazy_add+=add;
tree[id].lazy_add%=mod;
return;
}
push_down(id);
if(R<=tree[id<<1].R){
change_add(id<<1,L,R,add);
}
else if(L>=tree[id<<1|1].L){
change_add(id<<1|1,L,R,add);
}
else{
change_add(id<<1,L,tree[id<<1].R,add);
change_add(id<<1|1,tree[id<<1|1].L,R,add);
}
update(id);
return;
}
void change_tim(int id,int L,int R,long long tim){//区间乘法
if(tree[id].L==L && tree[id].R==R){
tree[id].lazy_tim*=tim;
tree[id].lazy_tim%=mod;
tree[id].lazy_add*=tim;
tree[id].lazy_add%=mod;
return;
}
push_down(id);
if(R<=tree[id<<1].R){
change_tim(id<<1,L,R,tim);
}
else if(L>=tree[id<<1|1].L){
change_tim(id<<1|1,L,R,tim);
}
else{
change_tim(id<<1,L,tree[id<<1].R,tim);
change_tim(id<<1|1,tree[id<<1|1].L,R,tim);
}
update(id);
return;
}
long long query(int id,int L,int R){//区间查询
if(tree[id].L==L && tree[id].R==R){
return (tree[id].sum*tree[id].lazy_tim%mod+(tree[id].R-tree[id].L+1)*tree[id].lazy_add%mod)%mod;
}
push_down(id);
if(R<=tree[id<<1].R){
return query(id<<1,L,R);
}
else if(L>=tree[id<<1|1].L){
return query(id<<1|1,L,R);
}
else{
return (query(id<<1,L,tree[id<<1].R)+query(id<<1|1,tree[id<<1|1].L,R))%mod;
}
}
int main(){
scanf("%d%d%lld",&n,&q,&mod);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
a[i]%=mod;
}
build_tree(1,1,n);
while(q--){
scanf("%d",&opt);
if(opt==1){//[l,r]*tim_num
scanf("%d%d%lld",&l,&r,&tim_num);
change_tim(1,l,r,tim_num);
}
if(opt==2){//[l,r]+add_num
scanf("%d%d%lld",&l,&r,&add_num);
change_add(1,l,r,add_num);
}
if(opt==3){//查询 sum[l,r]
scanf("%d%d",&l,&r);
printf("%lld\n",query(1,l,r));
}
}
return 0;
}