最规整的版本。
玩火需谨慎(&)
//Writer:GhostCai && His Yellow Duck
#include<iostream>
using namespace std;
const long long MAXN=200005;
long long n,m;
long long a[MAXN];
struct Node{
long long sum;
long long ls,rs,l,r;
long long lazy;
}node[MAXN];
long long cnt,root;
void pushup(long long now){
Node &o=node[now];
Node &nl=node[o.ls],&nr=node[o.rs];
o.sum = nl.sum + nr.sum ;
o.l = nl.l ;
o.r = nr.r ;
}
void pushdown(long long now){
Node &o=node[now];
Node &nl=node[o.ls],&nr=node[o.rs];
nl.lazy +=o.lazy ;
nr.lazy +=o.lazy ;
nl.sum +=o.lazy *(nl.r-nl.l+1);
nr.sum +=o.lazy *(nr.r-nr.l+1);
o.lazy = 0;
}
void build(long long L,long long R,long long now){
Node &o=node[now];
if(L==R){
o.sum = a[L];
o.ls = o.rs =-1;
o.l = o.r = L;
return ;
}
long long mid=(L+R)>>1;
build(L,mid,o.ls=cnt++);
build(mid+1,R,o.rs=cnt++);
pushup(now);
}
long long query(long long L,long long R,long long now){
Node &o=node[now];
Node &nl=node[o.ls],&nr=node[o.rs];
if(L<=o.l&&o.r<=R) return o.sum ;
pushdown(now);
long long mid=(o.l +o.r )>>1;
long long sum=0;
if(L<=mid) sum+=query(L,R,o.ls);
if(mid<R) sum+=query(L,R,o.rs);
return sum;
}
void updata(long long L,long long R,long long w,long long now){
Node &o=node[now];
Node &nl=node[o.ls],&nr=node[o.rs];
if(L<=o.l&&o.r<=R){
o.sum +=w*(o.r-o.l+1);
o.lazy +=w;
return ;
}
pushdown(now);
long long mid=(o.l+o.r)>>1;
if(L<=mid) updata(L,R,w,o.ls);
if(mid< R) updata(L,R,w,o.rs);
pushup(now);
}
int main(){
cin>>n>>m;
for(long long i=1;i<=n;i++) cin>>a[i];
build(1,n,root=cnt++);
long long q,x,y,z;
for(long long i=1;i<=m;i++){
cin>>q;
if(q==1){
cin>>x>>y>>z;
updata(x,y,z,root);
}else{
cin>>x>>y;
cout<<query(x,y,root)<<endl;
}
}
}
好写的版本
//Stay foolish,stay hungry,stay young,stay simple
#include<iostream>
#define ls now<<1
#define rs now<<1|1
using namespace std;
const int MAXN=200000;
int val[MAXN],lazy[MAXN];
int a[MAXN];
void pushup(int now){
val[now]=val[ls]+val[rs];
}
void pushdown(int now,int l,int r){
int mid=(l+r)>>1;
lazy[ls]+=lazy[now];
lazy[rs]+=lazy[now];
val[ls]+=lazy[now]*(mid-l+1);
val[rs]+=lazy[now]*(r-mid);
lazy[now]=0;
}
void build(int L,int R,int now){
if(L==R){
val[now]=a[L];//
return ;
}
int mid=(L+R)>>1;
build(L,mid,ls);
build(mid+1,R,rs);
pushup(now);
}
void updata(int L,int R,int l,int r,int now,int w){
if(L<=l&&r<=R){
lazy[now]+=w;
val[now]+=w*(r-l+1);
return ;
}
pushdown(now,l,r);
int mid=(l+r)>>1;
if(L<=mid) updata(L,R,l,mid,ls,w);
if(mid <R) updata(L,R,mid+1,r,rs,w);
pushup(now);
}
int query(int L,int R,int l,int r,int now){
if(L<=l&&r<=R){
return val[now];
}
int mid=(l+r)>>1;
int ret=0;
pushdown(now,l,r);
if(L<=mid) ret+=query(L,R,l,mid,ls);
if(mid <R) ret+=query(L,R,mid+1,r,rs);
return ret;
}
int n,m;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,n,1);
for(int i=1;i<=m;i++){
int q,x,y,z;
cin>>q;
if(q==1){
cin>>x>>y>>z;
updata(x,y,1,n,1,z);
}else{
cin>>x>>y;
cout<<query(x,y,1,n,1)<<endl;
}
}
return 0;
}
乘法标记+封装
#include<iostream>
#include<cstdio>
#include<cstring>
#define int long long
using namespace std;
const int MAXN=300005;
inline int rd(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10+c-'0',c=getchar();
return ret*f;
}
int p;
struct Seg{
#define ls now<<1
#define rs now<<1|1
#define mid ((l+r)>>1)
int sum[MAXN],add[MAXN],mut[MAXN],a[MAXN];
void pushup(int now){sum[now]=sum[ls]+sum[rs];}
void pushdown(int now,int l,int r){
mut[now]%=p;add[now]%=p;
mut[ls]*=mut[now];mut[ls]%=p;
mut[rs]*=mut[now];mut[rs]%=p;
add[ls]=add[ls]*mut[now]+add[now];
add[rs]=add[rs]*mut[now]+add[now];
sum[ls]=sum[ls]*mut[now]+(mid-l+1)*add[now];
sum[rs]=sum[rs]*mut[now]+(r-mid)*add[now];
add[ls]%=p;add[rs]%=p;sum[ls]%=p;sum[rs]%=p;
add[now]=0;mut[now]=1;
}
void build(int now,int l,int r){
if(l==r){sum[now]=a[l];mut[now]=1;return;}
build(ls,l,mid);
build(rs,mid+1,r);
mut[now]=1;//
pushup(now);
}
void updata_mut(int L,int R,int w,int now,int l,int r){
if(L<=l&&r<=R){sum[now]*=w;sum[now]%=p;mut[now]*=w;mut[now]%=p;add[now]*=w;add[now]%=p;return;}
pushdown(now,l,r);
if(L<=mid) updata_mut(L,R,w,ls,l,mid);
if(mid <R) updata_mut(L,R,w,rs,mid+1,r);
pushup(now);
}
void updata_add(int L,int R,int w,int now,int l,int r){
if(L<=l&&r<=R){sum[now]+=w*(r-l+1);sum[now]%=p;add[now]+=w;add[now]%=p;return;}
pushdown(now,l,r);
if(L<=mid) updata_add(L,R,w,ls,l,mid);
if(mid <R) updata_add(L,R,w,rs,mid+1,r);
pushup(now);
}
int query(int L,int R,int now,int l,int r){
if(L<=l&&r<=R){return sum[now];}
pushdown(now,l,r);
int ret=0;
if(L<=mid) ret+=query(L,R,ls,l,mid),ret%=p;
if(mid <R) ret+=query(L,R,rs,mid+1,r),ret%=p;
return ret%p;
}
}t;
int n,m;
signed main(){
n=rd();m=rd();p=rd();
for(int i=1;i<=n;i++) t.a[i]=rd();
t.build(1,1,n);
for(int i=1;i<=m;i++){
int x,y,w,q;
q=rd();
switch(q){
case 1:{
x=rd();y=rd();w=rd();
t.updata_mut(x,y,w%p,1,1,n);
break;
}
case 2:{
x=rd();y=rd();w=rd();
t.updata_add(x,y,w%p,1,1,n);
break;
}
case 3:{
x=rd();y=rd();
printf("%d
",t.query(x,y,1,1,n));
break;
}
}
}
return 0;
}