我知道这份代码很丑,但请麻烦帮忙调一下,非常感谢。调了很久,加了各种mod,所有变量都开的ll,标记也是先乘后加,但不知道问题出在哪……
#include <bits/stdc++.h>
#define N 500005
#define ll long long
#define ls p*2
#define rs p*2+1
using namespace std;
ll a[N],b[N];
ll n,m,u,v,w,cnt,num,tot,k,t,mod,q;
ll ans,anss;
struct node{
ll l,r,sum,lak,lab;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define sum(x) tree[x].sum
#define lak(x) tree[x].lak//lak表示乘标记
#define lab(x) tree[x].lab//lab表示加标记
}tree[N<<2];
void build(ll p,ll l,ll r){
l(p)=l;r(p)=r;lak(p)=1;
if(l==r){
sum(p)=a[l];
return;
}
ll mid=(l+r)>>1;
build(ls,l,mid);//ls表示左儿子,rs表示右儿子
build(rs,mid+1,r);
sum(p)=sum(ls)+sum(rs);
sum(p)%=mod;
}
void sp(ll p){//下传标记
//if(lab(p)==0&&lak(p)==1)return;
//cout<<lak(p)<<" "<<lab(p)<<endl;
if(lak(p)==0)lak(p)=mod;
lab(ls)=(lab(ls)+lab(p))%mod;
lab(rs)=(lab(rs)+lab(p))%mod;
lak(ls)=lak(ls)*lak(p)%mod;lak(rs)=lak(rs)*lak(p)%mod;
if(lak(ls)==0)lak(ls)=mod;
if(lak(rs)==0)lak(rs)=mod;
ll mid=(l(p)+r(p))>>1;
sum(ls)=sum(ls)*lak(p)%mod;
sum(rs)=sum(rs)*lak(p)%mod;
sum(ls)=sum(ls)+(lab(p)*(mid-l(p)+1)%mod);
sum(rs)=sum(rs)+(lab(p)*(r(p)-mid)%mod);
sum(ls)%=mod;sum(rs)%=mod;
lab(p)=0;lak(p)=1;
}
void add(ll p,ll l,ll r,ll d){
if(l<=l(p)&&r(p)<=r){
sum(p)+=d*(r(p)-l(p)+1);
sum(p)%=mod;
lab(p)+=d;
lab(p)%=mod;
return;
}
sp(p);
ll mid=(l(p)+r(p))>>1;
if(l<=mid)add(ls,l,r,d);
if(r>mid)add(rs,l,r,d);
sum(p)=sum(ls)+sum(rs);
sum(p)%=mod;
}
void ch(ll p,ll l,ll r,ll d){//乘法
if(l<=l(p)&&r(p)<=r){
sum(p)=sum(p)*d%mod;
lab(p)=lab(p)*d%mod;
lak(p)=lak(p)*d%mod;
if(lak(p)==0)lak(p)=mod;
return;
}
sp(p);
ll mid=(l(p)+r(p))>>1;
if(l<=mid)ch(ls,l,r,d);
if(r>mid)ch(rs,l,r,d);
sum(p)=sum(ls)+sum(rs);
sum(p)%=mod;
}
ll ask(ll p,ll l,ll r){
if(l<=l(p)&&r(p)<=r){
return sum(p);
}
sp(p);
ll mid=(l(p)+r(p))>>1,an=0;
if(l<=mid)an=(an+ask(ls,l,r))%mod;
if(r>mid)an=(an+ask(rs,l,r))%mod;
return an%mod;
}
signed main(){
cin>>n>>q>>mod;
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]%=mod;
build(1,1,n);
while(q--){
scanf("%lld",&w);
//cout<<endl<<w<<endl<<endl;
if(w==1){
scanf("%lld%lld%lld",&u,&v,&k);
ch(1,u,v,k%mod+mod);
}
if(w==2){
scanf("%lld%lld%lld",&u,&v,&k);
add(1,u,v,k%mod);
}
if(w==3){
scanf("%lld%lld",&u,&v);
cout<<ask(1,u,v)%mod<<'\n';
}
}
return 0;
}