标签:
三个数组sum, mul, add,具体操作看代码
要注意前面操作对当前的影响,及时pushback,统计祖先add&mul也要想清
以后做这种题目都要想清定义,每一步的影响,不然就都乱了
以后要自己想清造小数据过了后再去搞大数据拍,自己造的数据密度大很多的,而且先要保证正确性才行
非常不愉快,打完后找标程对拍,大数据不一样,调了好久,结果是标程有问题QwQ
以后全部用ll保平安啦
#include<cstdio> #define ll long long const int maxn=4e5+5; ll sumv[maxn],mulv[maxn],addv[maxn]; ll N,M,mod,p,q,w,x; void pushup(ll o,ll l,ll r){ sumv[o]=0; if(l<r) sumv[o]=sumv[o*2]+sumv[o*2+1]; sumv[o]*=mulv[o],sumv[o]%=mod; sumv[o]+=(r-l+1)*addv[o],sumv[o]%=mod; } void pushdown(ll o,ll l,ll r){ ll Mul=mulv[o],Add=addv[o],lc=o*2,rc=o*2+1,mid=(l+r)>>1; sumv[lc]=(sumv[lc]*Mul+(mid-l+1)*Add)%mod; sumv[rc]=(sumv[rc]*Mul+(r-mid)*Add)%mod; mulv[lc]=(mulv[lc]*Mul)%mod; mulv[rc]=(mulv[rc]*Mul)%mod; addv[lc]=(addv[lc]*Mul+Add)%mod; addv[rc]=(addv[rc]*Mul+Add)%mod; mulv[o]=1;addv[o]=0; } void add(ll o,ll l,ll r){ if(p<=l&&q>=r) addv[o]+=w,addv[o]%=mod; else{ pushdown(o,l,r); int mid=(l+r)/2; if(p<=mid) add(o*2,l,mid); if(q>mid) add(o*2+1,mid+1,r); } pushup(o,l,r); } void mul(ll o,ll l,ll r){ if(p<=l&&q>=r){ mulv[o]*=w,mulv[o]%=mod; addv[o]*=w,addv[o]%=mod; } else{ pushdown(o,l,r); int mid=(l+r)/2; if(p<=mid) mul(o*2,l,mid); if(q>mid) mul(o*2+1,mid+1,r); } pushup(o,l,r); } ll ret; void sum(ll o,ll l,ll r,ll Add,ll Mul){ if(p<=l&&q>=r){ ret+=Mul*sumv[o]+Add*(r-l+1); ret%=mod; } else{ int mid=(l+r)/2; if(p<=mid) sum(o*2,l,mid,(Add+Mul*addv[o])%mod,Mul*mulv[o]%mod); if(q>mid) sum(o*2+1,mid+1,r,(Add+Mul*addv[o])%mod,Mul*mulv[o]%mod); } } int main(){ scanf("%lld%lld",&N,&mod); for(int i=1;i<=3*N;i++) mulv[i]=1; for(int i=1;i<=N;i++){ scanf("%lld",&w); p=q=i; add(1,1,N); } scanf("%lld",&M); for(int i=1;i<=M;i++){ scanf("%lld",&x); if(x==1){ scanf("%lld%lld%lld",&p,&q,&w); mul(1,1,N); } else if(x==2){ scanf("%lld%lld%lld",&p,&q,&w); add(1,1,N); } else{ scanf("%lld%lld",&p,&q); ret=0; sum(1,1,N,0,1); printf("%lld\n",ret); continue; } } return 0; }
标签:
原文地址:http://www.cnblogs.com/xkui/p/4539833.html