支持区间加减,乘。询问区间和。
要注意的几点:
1.输出格式!!!!
2.$printf("")$语法要写对,不然的话能过编辑,半天调不出来。
3.位运算的时候$>>1$和$<<1$和$<<1|1$分清……
4.将什么$val[p]+=……,val[p]%=mod$ 要写到一句的时候,一定要记得$val[p]=val[p]+……$,不是$val[p]=……$
好了,这$4$点调了一上午$……$
代码奉上
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int mod;
struct linetree{
long long val[400010];
long long lazyp[400010];
long long lazym[400010];
inline void update(int p,int l,int r)
{
val[p]=(val[p]*lazym[p])%mod,
val[p]=(val[p]+(r-l)*lazyp[p])%mod;
return ;
}
inline void pushdown(int p,int l,int r)
{
update(p,l,r);
if(r-l>1)
{
lazyp[p<<1]=(lazyp[p<<1]*lazym[p]+lazyp[p])%mod,
lazym[p<<1]=(lazym[p<<1]*lazym[p])%mod;
lazyp[p<<1|1]=(lazyp[p<<1|1]*lazym[p]+lazyp[p])%mod,
lazym[p<<1|1]=(lazym[p<<1|1]*lazym[p])%mod;
}lazyp[p]=0,lazym[p]=1;
return ;
}
inline int build(int p,int l,int r)
{
lazym[p]=1;
if(r-l==1) {scanf("%lld",&val[p]),val[p]%=mod;return val[p];}
int mid=l+r>>1;
if(mid>l) val[p]=(val[p]+build(p<<1,l,mid))%mod;
if(mid<r) val[p]=(val[p]+build(p<<1|1,mid,r))%mod;
return val[p];
}
void setpluse(int p,int l,int r,int dl,int dr,long long pluse)
{
if(lazyp[p]!=0||lazym[p]!=1) pushdown(p,l,r);
if(l==dl&&r==dr){lazyp[p]=(lazyp[p]+pluse)%mod,pushdown(p,l,r);return ;}
int mid=l+r>>1;
if(mid>dl) setpluse(p<<1,l,mid,dl,min(mid,dr),pluse);else pushdown(p<<1,l,mid);
if(mid<dr) setpluse(p<<1|1,mid,r,max(dl,mid),dr,pluse);else pushdown(p<<1|1,mid,r);
val[p]=val[p<<1]+val[p<<1|1];
return ;
}
void setmulty(int p,int l,int r,int dl,int dr,long long multy)
{
if(lazyp[p]!=0||lazym[p]!=1) pushdown(p,l,r);
if(l==dl&&r==dr)
{lazyp[p]=(lazyp[p]*multy)%mod,lazym[p]=(lazym[p]*multy)%mod,pushdown(p,l,r);return ;}
int mid=l+r>>1;
if(mid>dl) setmulty(p<<1,l,mid,dl,min(mid,dr),multy);else pushdown(p<<1,l,mid);
if(mid<dr) setmulty(p<<1|1,mid,r,max(dl,mid),dr,multy);else pushdown(p<<1|1,mid,r);
val[p]=(val[p<<1]+val[p<<1|1])%mod;
return ;
}
int sum(int p,int l,int r,int dl,int dr)
{
if(lazyp[p]!=0||lazym[p]!=1) pushdown(p,l,r);
if(l==dl&&r==dr) return val[p];
int mid=l+r>>1;int res=0;
if(mid>dl) res+=sum(p<<1,l,mid,dl,min(dr,mid));
if(mid<dr) res+=sum(p<<1|1,mid,r,max(dl,mid),dr);
res%=mod;
return res;
}
}lt;
int n,m,t;
int u,v,opt;
signed main()
{
scanf("%d%d%d",&n,&m,&mod);
lt.build(1,0,n);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&opt,&u,&v);
if(opt==1) {scanf("%d",&t);lt.setmulty(1,0,n,u-1,v,t);}
if(opt==2) {scanf("%d",&t);lt.setpluse(1,0,n,u-1,v,t);}
if(opt==3) {printf("%d\n",lt.sum(1,0,n,u-1,v));}
}
return 0;
}