P3373 【模板】线段树 2 一直都是WA。。求调
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int n,m,mod;
int lz1[4*N],lz2[4*N],a[N];
int tree[4*N];
void buildTree(int p,int l,int r){
lz1[p]=0;lz2[p]=1;
if(l==r){
tree[p]=a[l];
tree[p]%=mod;
return;
}
int mid=(l+r)>>1;
buildTree(2*p,l,mid);
buildTree(2*p+1,mid+1,r);
tree[p]=tree[2*p]+tree[2*p+1];
tree[p]%=mod;
}
void pushdown(int p,int l,int r){//懒标下移
if(lz1[p]!=0||lz2[p]!=1){
int mid=(l+r)>>1;
tree[2*p]=(tree[2*p]*lz2[p]+(mid-l+1)*lz1[p])%mod;
tree[2*p+1]=(tree[2*p+1]*lz2[p]+(r-mid)*lz1[p])%mod;
lz2[2*p]=(lz2[2*p]*lz2[p])%mod;
lz2[2*p+1]=(lz2[2*p+1]*lz2[p])%mod;
lz1[2*p]=(lz1[2*p]*lz2[p]+lz1[p])%mod;
lz1[2*p+1]=(lz1[2*p+1]*lz2[p]+lz1[p])%mod;
lz1[p]=0;
lz2[p]=1;
}
}
void update1(int p,int l,int r,int x,int y,int v){//加
if(x<=l&&r<=y){
lz1[p]=(lz1[p]+v)%mod;
tree[p]+=(r-l+1)*v;
tree[p]%=mod;
return;
}
pushdown(p,l,r);
int mid=(l+r)>>1;
if(x<=mid)update1(2*p,l,mid,x,y,v);
if(y>mid)update1(2*p+1,mid+1,r,x,y,v);
tree[p]=tree[2*p]+tree[2*p+1];
tree[p]%=mod;
}
void update2(int p,int l,int r,int x,int y,int v){//乘
if(x<=l&&r<=y){
lz1[p]+=v;
tree[p]=(tree[p]*v)%mod;
lz2[p]=(lz2[p]*v)%mod;
lz1[p]=(lz1[p]*v)%mod;
return;
}
pushdown(p,l,r);
int mid=(l+r)>>1;
if(x<=mid)update2(2*p,l,mid,x,y,v);
if(y>mid)update2(2*p+1,mid+1,r,x,y,v);
tree[p]=tree[2*p]+tree[2*p+1];
tree[p]%=mod;
}
int query(int p,int l,int r,int x,int y){//查询
if(x<=l&&r<=y){
return tree[p];
}
pushdown(p,l,r);
int mid=(l+r)>>1;
int sum=0;
if(x<=mid)sum=(sum+query(2*p,l,mid,x,y))%mod;
if(y>mid)sum=(sum+query(2*p+1,mid+1,r,x,y))%mod;
return sum%mod;
}
signed main(){
cin>>n>>m>>mod;
for(int i=1;i<=n;i++){
scanf("%lld",a+i);
}
buildTree(1,1,n);
while(m--){
int opt,x,y,k;
scanf("%lld",&opt);
if(opt==1){
scanf("%lld%lld%lld",&x,&y,&k);
update2(1,1,n,x,y,k);
}else if(opt==2){
scanf("%lld%lld%lld",&x,&y,&k);
update1(1,1,n,x,y,k);
}else if(opt==3){
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
}
return 0;
}