https://www.luogu.com.cn/problem/P3373
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200009;
int n,m;
ll p,sum[N<<2],add[N<<2],mul[N<<2];
void pushdown(int o){
int lc=o<<1,rc=o<<1|1;
mul[lc]=mul[lc]*mul[o]%p;
mul[rc]=mul[rc]*mul[o]%p;
add[lc]=(add[lc]*mul[o]%p+add[o])%p;
add[rc]=(add[rc]*mul[o]%p+add[o])%p;
mul[o]=1,add[o]=0;
}
void maintain(int left,int right,int o){
int mid=(left+right)>>1,lc=o<<1,rc=o<<1|1;
sum[o]=0;
if(left<right)
sum[o]=(sum[lc]+sum[rc])%p;
sum[o]=(sum[o]*mul[o]%p+add[o]*(right-left+1))%p;
}
void update(int left,int right,int o,int l,int r,int op,ll val){
int mid=(left+right)>>1,lc=o<<1,rc=o<<1|1;
if(l<=left&&right<=r){
if(op==1){
add[o]=add[o]*val%p;
mul[o]=mul[o]*val%p;
}else
add[o]=(add[o]+val)%p;
}else{
pushdown(o);
if(l<=mid)
update(left,mid,lc,l,r,op,val);
else
maintain(left,mid,lc);
if(r>mid)
update(mid+1,right,rc,l,r,op,val);
else
maintain(mid+1,right,rc);
}
maintain(left,right,o);
}
ll query(int left,int right,int o,int l,int r){
int mid=(left+right)>>1,lc=o<<1,rc=o<<1|1;
if(l<=left&&right<=r){
maintain(left,right,o);
return sum[o];
}
pushdown(o);
ll ans=0;
if(l<=mid)
ans=(ans+query(left,mid,lc,l,r))%p;
else
maintain(left,mid,lc);
if(r>mid)
ans=(ans+query(mid+1,right,rc,l,r))%p;
else
maintain(mid+1,right,rc);
maintain(left,right,o);
return ans;
}
int main(){
for(int i=0;i<N<<2;i++)
mul[i]=1;
scanf("%d%d%lld",&n,&m,&p);
for(int i=1;i<=n;i++){
ll x;
scanf("%lld",&x);
update(1,n,1,i,i,2,x);
}
while(m--){
int op,l,r;
ll val;
scanf("%d",&op);
if(op!=3){
scanf("%d%d%lld",&l,&r,&val);
update(1,n,1,l,r,op,val);
}else{
scanf("%d%d",&l,&r);
ll ans=query(1,n,1,l,r);
printf("%lld\n",ans);
}
}
return 0;
}
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200009;
int n,m;
ll p,sum[N<<2],add[N<<2],mul[N<<2];
void pushdown(int left,int right,int o) {
int mid=(left+right)>>1,lc=o<<1,rc=o<<1|1;
mul[lc]=mul[lc]*mul[o]%p;
mul[rc]=mul[rc]*mul[o]%p;
add[lc]=(add[lc]*mul[o]%p+add[o])%p;
add[rc]=(add[rc]*mul[o]%p+add[o])%p;
sum[lc]=(sum[lc]*mul[o]%p+add[o]*(mid-left+1)%p)%p;
sum[rc]=(sum[rc]*mul[o]%p+add[o]*(right-mid)%p)%p;
mul[o]=1,add[o]=0;
}
void maintain(int o) {
int lc=o<<1,rc=o<<1|1;
sum[o]=(sum[lc]+sum[rc])%p;
}
void update(int left,int right,int o,int l,int r,int op,ll val) {
int mid=(left+right)>>1,lc=o<<1,rc=o<<1|1;
if(l<=left&&right<=r) {
if(op==1) {
add[o]=add[o]*val%p;
mul[o]=mul[o]*val%p;
sum[o]=sum[o]*val%p;
} else {
add[o]=(add[o]+val)%p;
sum[o]=(sum[o]+val*(right-left+1)%p)%p;
}
} else {
pushdown(left,right,o);
if(l<=mid)
update(left,mid,lc,l,r,op,val);
if(r>mid)
update(mid+1,right,rc,l,r,op,val);
maintain(o);
}
}
ll query(int left,int right,int o,int l,int r) {
int mid=(left+right)>>1,lc=o<<1,rc=o<<1|1;
if(l<=left&&right<=r)
return sum[o];
pushdown(left,right,o);
ll ans=0;
if(l<=mid)
ans=(ans+query(left,mid,lc,l,r))%p;
if(r>mid)
ans=(ans+query(mid+1,right,rc,l,r))%p;
return ans;
}
int main() {
for(int i=0; i<N<<2; i++)
mul[i]=1;
scanf("%d%d%lld",&n,&m,&p);
for(int i=1; i<=n; i++) {
ll x;
scanf("%lld",&x);
update(1,n,1,i,i,2,x);
}
while(m--) {
int op,l,r;
ll val;
scanf("%d",&op);
if(op!=3) {
scanf("%d%d%lld",&l,&r,&val);
update(1,n,1,l,r,op,val);
} else {
scanf("%d%d",&l,&r);
ll ans=query(1,n,1,l,r);
printf("%lld\n",ans);
}
}
return 0;
}