言归正传,开始讲解
定义线段树
struct node{
int l,r;//区间左右端点
long long val;//数据域
long long lazy_tag;//延迟更新标记
}t[400010];
构造线段树
void build(int p,int l,int r){
t[p].l=l;
t[p].r=r;
if(l==r){
t[p].val=a[l];
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].val=t[p*2].val+t[p*2+1].val;
return;
}
点更新(a[loc]+=k)
void change(int p,int loc,int k){
t[p].val+=k;
if(t[p].l==t[p].r) return;
int mid=(t[p].l+t[p].r)/2;
if(loc<=mid) change(p*2,loc,k);
else change(p*2+1,loc,k);
return;
}
小模块
long long get_val(int p){
return t[p].val+t[p].lazy_tag*(t[p].r-t[p].l+1);
}
lazy_tag的下传
void pushdown(int p){
if(t[p].lazy_tag==0) return;
t[p].val=get_val(p);
if(t[p].l<t[p].r){
t[p*2].lazy_tag+=t[p].lazy_tag;
t[p*2+1].lazy_tag+=t[p].lazy_tag;
}
t[p].lazy_tag=0;
return;
}
区间查询([l,r])
long long query(int p,int l,int r){ //查询[l,r]
if(l==t[p].l && r==t[p].r) return get_val(p);
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid) return query(p*2,l,r);
else if(l>=mid+1) return query(p*2+1,l,r);
else return query(p*2,l,mid)+query(p*2+1,mid+1,r);
return 0;
}
区间修改([l,r]+k)
void update(int p,int l,int r,int k){
if(l==t[p].l && r==t[p].r){
t[p].lazy_tag+=k;
return ;
}
int mid=(t[p].l+t[p].r)/2;
if(r<=mid) update(p*2,l,r,k);
else if(l>=mid+1) update(p*2+1,l,r,k);
else{
update(p*2,l,mid,k);
update(p*2+1,mid+1,r,k);
}
t[p].val+=k*(r-l+1);
return;
}
AC代码
#include<bits/stdc++.h>
using namespace std;
//定义
struct node{
int l,r;//区间左右端点
long long val;//数据域
long long lazy_tag;//延迟更新标记
};
node t[400010];
int n,m;
long long a[100010];
//构造线段树
void build(int p,int l,int r){
t[p].l=l;
t[p].r=r;
if(l==r){
t[p].val=a[l];
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].val=t[p*2].val+t[p*2+1].val;
return;
}
//点更新
void change(int p,int loc,int k){ //a[loc]+=k
t[p].val+=k;
if(t[p].l==t[p].r) return;
int mid=(t[p].l+t[p].r)/2;
if(loc<=mid) change(p*2,loc,k);
else change(p*2+1,loc,k);
return;
}
long long get_val(int p){
return t[p].val+t[p].lazy_tag*(t[p].r-t[p].l+1);
}
//lazy_tag的下传
void pushdown(int p){
if(t[p].lazy_tag==0) return;
t[p].val=get_val(p);
if(t[p].l<t[p].r){
t[p*2].lazy_tag+=t[p].lazy_tag;
t[p*2+1].lazy_tag+=t[p].lazy_tag;
}
t[p].lazy_tag=0;
return;
}
//区间查询
long long query(int p,int l,int r){ //查询[l,r]
if(l==t[p].l && r==t[p].r) return get_val(p);
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid) return query(p*2,l,r);
else if(l>=mid+1) return query(p*2+1,l,r);
else return query(p*2,l,mid)+query(p*2+1,mid+1,r);
return 0;
}
//区间修改
void update(int p,int l,int r,int k){
if(l==t[p].l && r==t[p].r){
t[p].lazy_tag+=k;
return ;
}
int mid=(t[p].l+t[p].r)/2;
if(r<=mid) update(p*2,l,r,k);
else if(l>=mid+1) update(p*2+1,l,r,k);
else{
update(p*2,l,mid,k);
update(p*2+1,mid+1,r,k);
}
t[p].val+=k*(r-l+1);
return;
}
int main(){
int opt,x,y,k;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++){
cin>>opt>>x>>y;
if(opt==1){
cin>>k;
update(1,x,y,k);
}
else{
cout<<query(1,x,y)<<endl;
}
}
return 0;
}