#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=571374;
struct node{
ll sum,la1,la2;
bool lc;
}tree[N<<2];
int a[N];
int n,m,p;
//建树
void up(int k){
tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}
void down(int k,int nl,int nr){
if(tree[k].lc){
//左下
tree[k<<1].sum=(tree[k<<1].sum*tree[k].la2)%p;
tree[k<<1].la1=(tree[k<<1].la1*tree[k].la2)%p;
if(tree[k<<1].lc){
tree[k<<1].la2=(tree[k<<1].la2*tree[k].la2)%p;
}else{
tree[k<<1].la2=tree[k].la2;
tree[k<<1].lc=1;
}
//右下
tree[k<<1|1].sum=(tree[k<<1|1].sum*tree[k].la2)%p;
tree[k<<1|1].la1=(tree[k<<1|1].la1*tree[k].la2)%p;
if(tree[k<<1|1].lc){
tree[k<<1|1].la2=(tree[k<<1|1].la2*tree[k].la2)%p;
}else{
tree[k<<1|1].la2=tree[k|1].la2;
tree[k<<1|1].lc=1;
}
tree[k].lc=0;
tree[k].la2=0;
}
if(tree[k].la1!=0){
tree[k<<1].sum=(tree[k<<1].sum+nl*tree[k].la1)%p;
tree[k<<1].la1=(tree[k<<1].la1+tree[k].la1)%p;
tree[k<<1|1].sum=(tree[k<<1|1].sum+nr*tree[k].la1)%p;
tree[k<<1|1].la1=(tree[k<<1|1].la1+tree[k].la1)%p;
tree[k].la1=0;
}
}
void build(int l,int r,int k){
if(l==r){
tree[k].sum=a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
up(k);
}
//查询
ll query(int ql,int qr,int l,int r,int k){
if(ql<=l&&qr>=r)return tree[k].sum;
int mid=(l+r)>>1;
down(k,mid-l+1,r-mid);
ll ret=0;
if(ql<=mid)ret=(ret+query(ql,qr,l,mid,k<<1))%p;
if(qr>mid)ret=(ret+query(ql,qr,mid+1,r,k<<1|1))%p;
return ret;
}
//更改
void add(int ql,int qr,int c,int l,int r,int k){
if(ql<=l&&qr>=r){
tree[k].sum+=(r-l+1)*c;
tree[k].la1+=c;
//if(tree)
return;
}
int mid=(l+r)>>1;
down(k,mid-l+1,r-mid);
if(ql<=mid)add(ql,qr,c,l,mid,k<<1);
if(qr>mid)add(ql,qr,c,mid+1,r,k<<1|1);
up(k);
}
void tim(int ql,int qr,int c,int l,int r,int k){//乘法
if(ql<=l&&qr>=r){
tree[k].sum=(tree[k].sum*c)%p;
tree[k].la1=(tree[k].la1*c)%p;
tree[k].la2=(tree[k].la2*c)%p;
if(tree[k].lc){
tree[k].la2=(tree[k].la2*c)%p;
}else{
tree[k].la2=c;
tree[k<<1|1].lc=1;
}
return;
}
int mid=(l+r)>>1;
down(k,mid-l+1,r-mid);
if(ql<=mid)tim(ql,qr,c,l,mid,k<<1);
if(qr>mid)tim(ql,qr,c,mid+1,r,k<<1|1);
up(k);
}
int main(){
cin>>n>>m>>p;
for(int i=1;i<=n;i++){
cin>>a[i];
}build(1,n,1);
int l,x,y,k;
while(m--){
cin>>l;
if(l==1){
cin>>x>>y>>k;
tim(x,y,k,1,n,1);
}else if(l==2){
cin>>x>>y>>k;
add(x,y,k,1,n,1);
}else if(l==3){
cin>>x>>y;
cout<<query(x,y,1,n,1)<<'\n';
}
}
}
自测数据:
输入
5 5 1145
1 2 3 4 5
2 3 5 4
1 1 4 5
3 3 4
3 3 3
3 4 4
期望输出
75
30
45
实际输出
47
7
40