原题 线段树2调了半天,只有30pts,求调。
#include<bits/stdc++.h>
using namespace std;
inline long long read(){
long long ans=0;
char c=getchar();
while(!isdigit(c)){
c=getchar();
}
while(isdigit(c)){
ans=ans*10+c-'0';
c=getchar();
}
return ans;
}
const int MAXN=100005;
long long mod,n,m,a[MAXN],tree[MAXN*4],add[MAXN*4],mul[MAXN*4];
inline void push_down(long long p,long long len){
tree[p*2]=(tree[p*2]*mul[p]+add[p]*(len-len/2))%mod;
tree[p*2+1]=(tree[p*2+1]*mul[p]+add[p]*(len/2))%mod;
mul[p*2]=(mul[p*2]*mul[p])%mod;
mul[p*2+1]=(mul[p*2+1]*mul[p])%mod;
add[p*2]=(add[p*2]*mul[p]+add[p])%mod;
add[p*2+1]=(add[p*2+1]*mul[p]+add[p])%mod;
add[p]=0;
mul[p]=1;
}
void build(long long l=1,long long r=n,long long p=1){
add[l]=0;
mul[l]=1;
if(l==r){
tree[p]=a[l];
return ;
}else{
long long mid=(l+r)/2;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
tree[p]=tree[p*2]+tree[p*2+1];
}
tree[p]=tree[p]%mod;
return ;
}
void update1(long long l,long long r,long long d,long long p=1,long long cl=1,long long cr=n){
if(cl>r||cr<l){
return ;
}else if(cl>=l&&cr<=r){
tree[p]=(tree[p]*d)%mod;
mul[p]=(mul[p]*d)%mod;
add[p]=(add[p]*d)%mod;
return ;
}else{
long long mid=(cl+cr)/2;
push_down(p,cr-cl+1);
update1(l,r,d,p*2,cl,mid);
update1(l,r,d,p*2+1,mid+1,cr);
tree[p]=(tree[p*2]+tree[p*2+1])%mod;
return ;
}
}
void update2(long long l,long long r,long long d,long long p=1,long long cl=1,long long cr=n){
if(cl>r||cr<l){
return;
}else if(cl>=l&&cr<=r){
tree[p]=(tree[p]+(cr-cl+1)*d)%mod;
add[p]=(add[p]+d)%mod;
}else{
long long mid=(cl+cr)/2;
push_down(p,cr-cl+1);
update2(l,r,d,p*2,cl,mid);
update2(l,r,d,p*2+1,mid+1,cr);
tree[p]=(tree[p*2]+tree[p*2+1])%mod;
}
}
long long query(long long l,long long r,long long p=1,long long cl=1,long long cr=n){
if(cl>r||cr<l){
return 0;
}else if(cl>=l&&cr<=r){
return tree[p];
}else{
long long mid=(cl+cr)/2;
push_down(p,cr-cl+1);
return (query(l,r,p*2,cl,mid)+query(l,r,p*2+1,mid+1,cr))%mod;
}
}
int main(){
n=read();
m=read();
mod=read();
for(int i=1;i<=n;i++){
a[i]=read();
}
build();
for(int i=0;i<m;i++){
long long opr=read(),l=read(),r=read();
if(opr==1){
long long d=read();
update1(l,r,d);
}else if(opr==2){
long long d=read();
update2(l,r,d);
}else{
printf("%lld\n",query(l,r));
}
}
return 0;
}