线段树+懒标记 (区间修改,区间查询)

原作者:董晓


P3372 【模板】线段树 1

// 结构体版
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 100005
#define LL long long
#define lc u<<1
#define rc u<<1|1
LL w[N];
struct Tree{ //线段树
LL l,r,sum,add;
}tr[N*4];
void pushup(LL u){ //上传
tr[u].sum=tr[lc].sum+tr[rc].sum;
}
void pushdown(LL u){ //下传
if(tr[u].add){
tr[lc].sum+=tr[u].add*(tr[lc].r-tr[lc].l+1),
tr[rc].sum+=tr[u].add*(tr[rc].r-tr[rc].l+1),
tr[lc].add+=tr[u].add,
tr[rc].add+=tr[u].add,
tr[u].add=0;
}
}
void build(LL u,LL l,LL r){ //建树
tr[u]={l,r,w[l],0};
if(l==r) return;
LL m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
pushup(u);
}
void change(LL u,LL l,LL r,LL k){ //区修
if(l<=tr[u].l&&tr[u].r<=r){
tr[u].sum+=(tr[u].r-tr[u].l+1)*k;
tr[u].add+=k;
return;
}
LL m=tr[u].l+tr[u].r>>1;
pushdown(u);
if(l<=m) change(lc,l,r,k);
if(r>m) change(rc,l,r,k);
pushup(u);
}
LL query(LL u,LL l,LL r){ //区查
if(l<=tr[u].l && tr[u].r<=r) return tr[u].sum;
LL m=tr[u].l+tr[u].r>>1;
pushdown(u);
LL sum=0;
if(l<=m) sum+=query(lc,l,r);
if(r>m) sum+=query(rc,l,r);
return sum;
}
int main(){
int n,m,op,x,y,k;
cin>>n>>m;
for(int i=1; i<=n; i ++) cin>>w[i];
build(1,1,n);
while(m--){
cin>>op>>x>>y;
if(op==2)cout<<query(1,x,y)<<endl;
else cin>>k,change(1,x,y,k);
}
return 0;
}

P3374 【模板】树状数组 1

#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define lc u<<1
#define rc u<<1|1
#define N 500005
int w[N];
struct Tree{
int l,r,sum;
}tr[N*4];
void pushup(int u){ //上传
tr[u].sum=tr[lc].sum+tr[rc].sum;
}
void build(int u,int l,int r){
tr[u]={l,r,w[l]};
if(l==r) return;
int m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
pushup(u);
}
void change(int u,int x,int k){ //点修
if(tr[u].l==x&&tr[u].r==x){
tr[u].sum+=k;
return;
}
int m=tr[u].l+tr[u].r>>1;
if(x<=m) change(lc,x,k);
if(x>m) change(rc,x,k);
pushup(u);
}
int query(int u,int l,int r){ //区查
if(l>tr[u].r || r<tr[u].l) return 0;
if(l<=tr[u].l&&tr[u].r<=r) return tr[u].sum;
return query(lc,l,r)+query(rc,l,r);
}
int main(){
ios::sync_with_stdio(0);
int n,m,op,x,y;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i];
build(1,1,n);
while(m--){
cin>>op>>x>>y;
if(op==1) change(1,x,y);
else cout<<query(1,x,y)<<endl;
}
return 0;
}

P3368 【模板】树状数组 2

#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 500005
#define LL long long
#define lc u<<1
#define rc u<<1|1
LL w[N];
struct Tree{ //线段树
LL l,r,sum,add;
}tr[N*4];
void pushup(LL u){ //上传
tr[u].sum=tr[lc].sum+tr[rc].sum;
}
void pushdown(LL u){ //下传
if(tr[u].add){
tr[lc].sum+=tr[u].add*(tr[lc].r-tr[lc].l+1),
tr[rc].sum+=tr[u].add*(tr[rc].r-tr[rc].l+1),
tr[lc].add+=tr[u].add,
tr[rc].add+=tr[u].add,
tr[u].add=0;
}
}
void build(LL u,LL l,LL r){ //建树
tr[u]={l,r,w[l],0};
if(l==r) return;
LL m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
pushup(u);
}
void change(LL u,LL x,LL y,LL k){ //区修
if(x>tr[u].r || y<tr[u].l) return;
if(x<=tr[u].l && tr[u].r<=y){
tr[u].sum+=(tr[u].r-tr[u].l+1)*k;
tr[u].add+=k;
return;
}
pushdown(u);
change(lc,x,y,k);
change(rc,x,y,k);
pushup(u);
}
LL query(LL u,LL x){ //点查
if(x>tr[u].r || x<tr[u].l) return 0;
if(x==tr[u].l && tr[u].r==x) return tr[u].sum;
pushdown(u);
return query(lc,x)+query(rc,x);
}
int main(){
ios::sync_with_stdio(0);
int n,m,op,x,y,k;
cin>>n>>m;
for(int i=1; i<=n; i ++) cin>>w[i];
build(1,1,n);
while(m--){
cin>>op>>x;
if(op==2)cout<<query(1,x)<<endl;
else cin>>y>>k,change(1,x,y,k);
}
return 0;
}

posted on   swj2529411658  阅读(11)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示