AC

♻️lzhh_lzhh26  •  13天前


/*
线段树:叶子节点就是数组
父节点(i)为子节点(2*i,2*i+1)汇总信息 
*/ 
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct TreeNode{
	int l,r;
	long long val;
	long long lazy;		//子节点待标记的值 
}tree[400005];		//习惯上长度皆为n*4 
long long d[100005];		//初始数组 
void maketree(int node,int l,int r){		//递归建区间l,r之间的树 
	tree[node].l=l;
	tree[node].r=r; 
	if(l==r){		//叶节点 
		tree[node].val=d[l];
	}else{
		int mid=(l+r)/2;
		maketree(node*2,l,mid);		//建左子树
		maketree(node*2+1,mid+1,r);		//建右子树 
		tree[node].val+=tree[node*2].val+tree[node*2+1].val;		//汇总父节点 
	}
}
void pushdown(int node){		//把k往下推 
	if(tree[node].lazy){
		tree[node*2].val+=(tree[node*2].r-tree[node*2].l+1)*tree[node].lazy;
		tree[node*2+1].val+=(tree[node*2+1].r-tree[node*2+1].l+1)*tree[node].lazy;
		tree[node*2].lazy+=tree[node].lazy;		//子节点也可能有子节点,不能丢掉待更新信息 
		tree[node*2+1].lazy+=tree[node].lazy;
		tree[node].lazy=0;
	}
	
}
//下面的所有函数,l r代表总区间,x y代表操作区间 
void addk(int node,int l,int r,int x,int y,int k){		
	if(x<=l&&r<=y){		//[x,y]包含[l,r]
		tree[node].val+=(r-l+1)*k;
		tree[node].lazy+=k;
	}
	else if(y<l||r<x) return;		//[x,y]在[l,r]之外,不更新 
	else{		//半包含 
		int mid=(l+r)/2;
		pushdown(node);
		addk(node*2,l,mid,x,y,k);
		addk(node*2+1,mid+1,r,x,y,k);		//一直拆到前两种情况出现 
		tree[node].val=tree[node*2].val+tree[node*2+1].val;
	}
}
long long getsum(int node,int l,int r,int x,int y){
	if(x<=l&&r<=y) return tree[node].val;		//[x,y]包含[l,r]
	else if(y<l||r<x) return 0;		//[x,y]在[l,r]之外,不更新
	else{			//半包含 
		int mid=(l+r)/2;
		pushdown(node);
		return getsum(node*2,l,mid,x,y)+getsum(node*2+1,mid+1,r,x,y);		//同理,拆下去 
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>d[i];
	maketree(1,1,n);		//朴实无华先把树建好 
	while(m--){
		int op,x,y,k;
		cin>>op;
		if(op==1){
			cin>>x>>y>>k;
			addk(1,1,n,x,y,k);
		}
		if(op==2){
			cin>>x>>y;
			cout<<getsum(1,1,n,x,y)<<endl; 
		}
	}
	return 0;
}

评论:

请先登录,才能进行评论