社区讨论

求助!

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

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@locrwfl9
此快照首次捕获于
2023/10/30 18:44
2 年前
此快照最后确认于
2023/11/05 05:29
2 年前
查看原帖
CPP
//P3372
#include <cstdio>
const int maxn=100005;
int a[maxn],t[maxn<<2],lazy[maxn<<2];

void up(int node){
	//从子树更新节点 
	t[node]=t[node<<1]+t[node<<1|1];
	return;
}
void down(int node){
	//将节点的lt更新到子树上 
	if(lazy[node]){
		lazy[node<<1]+=lazy[node];
		lazy[node<<1|1]+=lazy[node];
		t[node<<1]+=lazy[node];
		t[node<<1|1]+=lazy[node];
		lazy[node]=0;
	}
	return;
}
void buildtree(int node,int l,int r){
	//建树 
	if(l==r){
		t[node]=a[l];
		return;
	}
	int m=l+((r-l)>>1);
	buildtree(node<<1,l,m);
	buildtree(node<<1|1,m+1,r);
	up(node);
	return;
}
int query(int l1,int r1,int l,int r,int node){
	//区间查询 
	if(l1<=l && r<=r1)
		return t[node];
	down(node);
	int ret=0,m=l+((r-l)>>1);
	if(l1<=m) ret+=query(l1,r1,l,m,node<<1);
	if(r1>m)  ret+=ret,query(l1,r1,m+1,r,node<<1|1);
	return ret;
}
void add(int l1,int r1,int v,int l,int r,int node){
	//区间添加 
	if(l1<=l && r<=r1){
		lazy[node]+=v;
		t[node]+=v;
		return;
	}
	down(node);
	int m=l+((r-l)>>1);
	if(l1<=m) add(l1,r1,v,l,m,node<<1);
	if(m<r1)  add(l1,r1,v,m+1,r,node<<1|1);
	up(node);
	return;
}

int main(){
	int n,m,f,x,y,k;
	scanf("%d %d",&n,&m);
	for(int i=1; i<=n; ++i)
		scanf("%d",&a[i]);
	buildtree(1,1,n);
	for(int i=1; i<=m; ++i){
		scanf("%d",&f);
		switch(f){
			case 1:
				scanf("%d %d %d",&x,&y,&k);
				add(x,y,k,1,n,1);
				break;
			case 2:
				scanf("%d %d",&x,&y);
				printf("%d\n",query(x,y,1,n,1));
				break;
			default:
				break;
		}
	}
	return 0;
}
样例都过不了

回复

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

正在加载回复...