样例可以过,但是提交全 wa。
码风比较丑,调对必关。
#include<iostream>
#include<cstdio>
#define int long long
#define lp p<<1
#define rp p<<1|1
using namespace std;
const int M=1e5+5;
int a[M],mod;
struct node{
int l,r,sum;
int add,mul;
void tag(int ak,int mk){
if(ak!=0){
add=(add+ak)%mod;
sum=(sum+(r-l+1)*ak)%mod;
}
if(mk!=1){
add=(add*mk)%mod;
sum=(sum*mk)%mod;
mul=(mul*mk)%mod;
}
}
};
node tree[M<<2];
void build(int l,int r,int p){
tree[p].l=l;tree[p].r=r;
tree[p].mul=1;
if(l==r){
tree[p].sum=a[l];
return;
}
int mid=l+(r-l)/2;
build(l,mid,lp);
build(mid+1,r,rp);
tree[p].sum=(tree[lp].sum+tree[rp].sum)%mod;
}
void down(int p){
tree[lp].tag(tree[p].add,tree[p].mul);
tree[rp].tag(tree[p].add,tree[p].mul);
tree[p].add=0;
tree[p].mul=1;
}
void update(int l,int r,int ak,int mk,int p){
if(tree[p].l==l&&tree[p].r==r){tree[p].tag(ak,mk);return;}
down(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(r<=mid)update(l,r,ak,mk,lp);
else if(l>mid)update(l,r,ak,mk,rp);
else{
update(l,mid,ak,mk,lp);
update(mid+1,r,ak,mk,rp);
}
tree[p].sum=(tree[lp].sum+tree[rp].sum)%mod;
}
int query(int l,int r,int p){
if(tree[p].l==l&&tree[p].r==r)return tree[p].sum;
down(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(r<=mid)return query(l,r,lp);
else if(l>mid)return query(l,r,rp);
else return (query(l,mid,lp)+query(mid+1,r,rp))%mod;
}
signed main(){
int n,q;
scanf("%lld%lld%lld",&n,&q,&mod);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,n,1);
while(q--){
int op,x,y,k;
scanf("%lld%lld%lld",&op,&x,&y);
if(op==1){
scanf("%lld",&k);
update(x,y,0,k,1);
}else if(op==2){
scanf("%lld",&k);
update(x,y,k,1,1);
}else{
printf("%lld\n",query(x,y,1)%mod);
}
}
return 0;
}