社区讨论

0分求调玄关....代码有注释,自认为马蜂良好

P3372【模板】线段树 1参与者 3已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@m3v9771g
此快照首次捕获于
2024/11/24 15:04
去年
此快照最后确认于
2025/11/04 14:01
4 个月前
查看原帖

rt

CPP
#include<bits/stdc++.h>
using namespace std;
#define lc p<<1
#define rc p<<1|1
const int N=5e5+5;
int w[N];

struct node { //结构体
	int l,r,sum,lazzy;
} tr[N*4];

void build(int p,int l,int r) { //建树
	tr[p]= {l,r,w[l]};
	if(r==l) return;//是叶子节点返回
	int m=r+l>>1;//非叶子节点则裂开
	build(lc,l,m);
	build(rc,m+1,r);
	tr[p].sum=tr[lc].sum+tr[rc].sum;
}

void pushup(int p) { //上传
	tr[p].sum=tr[lc].sum+tr[rc].sum;
}

void pushdown(int p) {//下传
	tr[lc].sum=tr[lc].lazzy*(tr[lc].r-tr[lc].l-1);
	tr[rc].sum=tr[rc].lazzy*(tr[rc].r-tr[rc].l-1);
	tr[lc].lazzy+=tr[p].lazzy;
	tr[rc].lazzy+=tr[p].lazzy;
	tr[p].lazzy=0;
}

void update(int p,int x,int k) { //点修改
	if(tr[p].l==x&&tr[p].r==x) { //叶子节点回推
		tr[p].sum+=k;
		return;
	}
	int m=tr[p].l+tr[p].r>>1;
	if(x<=m) update(lc,x,k);
	if(x>m)  update(rc,x,k);
	tr[p].sum=tr[lc].sum+tr[rc].sum;
}

void update1(int p,int x,int y,int k) {//区间修改
	if(x<=tr[p].l&&y>=tr[p].r) { //叶子节点回推
		tr[p].sum+=(tr[p].l-tr[p].r+1)*k;
		tr[p].lazzy+=k;
		return;
	}
	int m=tr[p].l+tr[p].r>>1;
	pushdown(p);
	if(x<=m) update1(lc,x,y,k);
	if(y>m) update1(rc,x,y,k);
	pushup(p);
}

int query(int p,int x,int y) { //区间查询
	if(x<=tr[p].l&&y>=tr[p].r) {
		return tr[p].sum;
	}
	int m=tr[p].l+tr[p].r>>1;
	int sum=0;
	if(x<=m) sum+=query(lc,x,y);
	if(y>m) sum+=query(rc,x,y);
	return sum;
}

int n,m;
int a,x,y,k;

int main() {
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>w[i];
	}
	build(1,1,n);
	for(int i=1;i<=m;i++){
		cin>>a;
		if(a==1){
			cin>>x>>y>>k;
			update1(1,x,y,k);
		}
		if(a==2){
			cin>>x>>y;
			cout<<query(1,x,y)<<endl;
		}
	}
	return 0;
}

回复

5 条回复,欢迎继续交流。

正在加载回复...