依旧是单纯地存个板。
指针实现。
区间修改区间查询
#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
const int N = 400010;
int n,m;
int a[N];
struct node{
ll sum,flag;
node *ls,*rs;
void update(){
sum=ls->sum+rs->sum;
}
void pushdown(int l,int r){
if(flag){
int mid=(l+r)>>1;
ls->sum+=(long long)(mid-l+1)*flag;
ls->flag+=flag;
rs->sum+=(long long)(r-mid)*flag;
rs->flag+=flag;
flag=0;
}
}
}pool[N],*tail=pool,*root;
node *build(int l,int r){
node *bt=++tail;
if(l==r){
bt->sum=a[l];
bt->flag=0;
}
else{
int mid=(l+r)>>1;
bt->ls=build(l,mid);
bt->rs=build(mid+1,r);
bt->update();
bt->flag=0;
}
return bt;
}
void modify(node *bt,int l,int r,int pos,int val,int delta){
if(pos<=l&&val>=r){
bt->sum+=(long long)(r-l+1)*delta;
bt->flag+=delta;
return ;
}
int mid=(l+r)>>1;
bt->pushdown(l,r);
if(pos<=mid) modify(bt->ls,l,mid,pos,val,delta);
if(val>mid) modify(bt->rs,mid+1,r,pos,val,delta);
bt->update();
}
ll query(node *bt,int l,int r,int pos,int val){
if(pos<=l&&val>=r)
return bt->sum;
int mid=l+r>>1;
bt->pushdown(l,r);
ll ans=0;
if(pos<=mid) ans+=query(bt->ls,l,mid,pos,val);
if(val>mid) ans+=query(bt->rs,mid+1,r,pos,val);
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
root=build(1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++){
int d;
scanf("%d",&d);
if(d==1){
int l,r,delta;
scanf("%d%d%d",&l,&r,&delta);
modify(root,1,n,l,r,delta);
}
if(d==2){
int l,r;
scanf("%d%d",&l,&r);
printf("%lld\n",query(root,1,n,l,r));
}
}
return 0;
}
数组
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N = 4000010;
int n,m;
int a[N];
struct node{
ll sum,flag;
int l,r;
}tree[N];
void pushdown(int root){
int flag=tree[root].flag;
int l=tree[root].l,r=tree[root].r;
if(flag){
int mid=(l+r)>>1;
tree[root<<1].flag+=flag;
tree[root<<1|1].flag+=flag;
tree[root<<1|1].sum+=(long long)(r-mid)*flag;
tree[root<<1].sum+=(long long)(mid-l+1)*flag;
tree[root].flag=0;
}
}
void build(int root,int l,int r){
tree[root].l=l,tree[root].r=r;
if(l==r){
tree[root].sum=a[l];
tree[root].flag=0;
}
else{
int mid=(l+r)>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
tree[root].flag=0;
}
}
void modify(int root,int pos,int val,int delta){
int l=tree[root].l,r=tree[root].r;
if(l>=pos&&r<=val){
tree[root].sum+=(long long)(r-l+1)*delta;
tree[root].flag+=delta;
return ;
}
int mid=(l+r)>>1;
pushdown(root);
if(pos<=mid) modify(root<<1,pos,val,delta);
if(val>mid) modify(root<<1|1,pos,val,delta);
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
}
ll query(int root,int pos,int val){
int l=tree[root].l,r=tree[root].r;
if(l>=pos&&r<=val)
return tree[root].sum;
ll ans=0;
pushdown(root);
int mid=(l+r)>>1;
if(pos<=mid) ans+=query(root<<1,pos,val);
if(val>mid) ans+=query(root<<1|1,pos,val);
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++){
int d;
scanf("%d",&d);
if(d==1){
int l,r,delta;
scanf("%d%d%d",&l,&r,&delta);
modify(1,l,r,delta);
}
if(d==2){
int l,r;
scanf("%d%d",&l,&r);
printf("%lld\n",query(1,l,r));
}
}
return 0;
}