社区讨论

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

讨论操作

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

当前回复
4 条
当前快照
1 份
快照标识符
@mibljhni
此快照首次捕获于
2025/11/23 18:50
4 个月前
此快照最后确认于
2025/11/23 20:08
4 个月前
查看原帖
AC代码:
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
#define ll long long
#define LC 2*cur
#define RC 2*cur+1
ll a[N];
struct Node{
	int l,r;
	ll value,tag;
	int len(){
		return r-l+1;
	}
}tree[N*4];
void pushup(int cur){
	tree[cur].value=tree[LC].value+tree[RC].value;
}
void build(int cur,int l,int r){
	tree[cur].l=l,tree[cur].r=r;
	if(l==r){
		tree[cur].value=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(LC,l,mid);
	build(RC,mid+1,r);
	pushup(cur);
}
void work(int cur,ll delta){
	tree[cur].value+=(tree[cur].len()*delta);
	tree[cur].tag+=delta;
}
void pushdown(int cur){
	if(tree[cur].tag>0){
		work(LC,tree[cur].tag),work(RC,tree[cur].tag);
		tree[cur].tag=0;
	}
}
void update(int cur,int l,int r,ll delta){
	if(l<=tree[cur].l&&r>=tree[cur].r){
		work(cur,delta);
		return;
	}
	pushdown(cur);
	int mid=(tree[cur].r+tree[cur].l)/2;
	if(mid>=l)update(LC,l,r,delta);
	if(mid<r)update(RC,l,r,delta);
	pushup(cur);
}
ll query(int cur,int l,int r){
	if(l<=tree[cur].l&&r>=tree[cur].r)return tree[cur].value;
	pushdown(cur);
	ll ans=0;
	int mid=(tree[cur].r+tree[cur].l)/2;
	if(mid>=l)ans+=query(LC,l,r);
	if(mid<r)ans+=query(RC,l,r);
	return ans;
}
int n,m;
int main(){
	cin >> n >> m;
	for(int i=1;i<=n;i++){
		cin >> a[i];
	}
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int op,x,y;
		ll k;
		cin >> op >> x >> y;
		if(op==1){
			cin >> k;
			update(1,x,y,k);
		}
		else {
			cout << query(1,x,y) << '\n';
		}
	}
	return 0;
}
为啥query和update函数中向下递推的部分不能写成这样
CPP
if(mid>=l)ans+=query(LC,l,mid);
if(mid<r)ans+=query(RC,mid+1,r);
以及这样
CPP
if(mid>=l)update(LC,l,mid,delta);
	if(mid<r)update(RC,mid+1,r,delta);
这样写是0pts但我不知道为啥

回复

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

正在加载回复...