线段树求条
查看原帖
线段树求条
656447
__Ship_楼主2025/1/16 16:44
#include<bits/stdc++.h>
#define int long long
using namespace std;
int tag[400050],n,m,a[400050];
struct node{
	int l,r;
	int date;
}tree[400005];//idx表示下标 
void build(int idx,int l,int r){
	tree[idx].l=l;
	tree[idx].r=r;
	if(l==r){
		tree[idx].date=a[l];
		return ;
	}
	int mid=(l+r)/2;
	build(2*idx,l,mid);//建左子树 
	build(2*idx+1,mid+1,r);//建右子树
	tree[idx].date=tree[2*idx].date+tree[2*idx+1].date;//向上传递信息 
}
void fun(int idx,int l,int r,int k){//k代表整体要加上的数 
	tag[idx]=tag[idx]+k;
    tree[idx].date+=k*(r-l+1);
}
void pushdown(int idx,int l,int r){
   int mid=(l+r)/2;
   fun(2*idx,l,mid,tag[idx]);
   fun(2*idx+1,mid+1,r,tag[idx]);
   tag[idx]=0;
   //每次更新两个儿子节点。以此不断向下传递 
}
void update(int tl,int tr,int l,int r,int idx,int k){
	if(l>=tl&&r<=tr){
        tree[idx].date+=k*(r-l+1);
        tag[idx]+=k;
        return ;
    }
	pushdown(idx,l,r);
	int mid=(l+r)/2;
	if(tl<=mid){
		update(tl,tr,l,mid,idx*2,k);
	} 
	if(tr>mid){
		update(tl,tr,mid+1,r,idx*2+1,k);
	}
	tree[idx].date=tree[2*idx].date+tree[2*idx+1].date;//向上传递信息 
}
int operate(int tl,int tr,int l,int r,int idx){
	int ret=0;
	if(l>=tl&&r<=tr){
		return tree[idx].date;
	}
	int mid=(l+r)/2;
	pushdown(idx,l,r);
	if(tl<=mid){
		ret+=operate(l,tr,l,mid,idx*2);
	} 
	if(tr>mid){
		ret+=operate(tl,tr,mid+1,r,idx*2+1);
	}
	return ret;
}
signed main(){
	cin>>n>>m;
	for(int i = 1 ; i <= n ; i++){
		cin>>a[i];
	}
	build(1,1,n);
	while(m--){
		int op,x,y,z;
		cin>>op;
		if(op==1){
			cin>>x>>y>>z;
			update(x,y,1,n,1,z);
		}
		else{
			cin>>x>>y;
			cout<<operate(x,y,1,n,1)<<endl;
		}
	}
	return 0;
}

2025/1/16 16:44
加载中...